How to Implement a Class That Returns the Iterator of a Container or the Pointer of an Array in C++?

2024-06-17C++

These are used to declare variables that will receive the return values of std::begin() and std::end(). Usually, you can use auto, but I created this because there are cases where auto can’t be used. There’s no need to worry about SFINAE, and it’s surprisingly easy to implement.

Implementation and Example

Implementation

#include <iterator>
#include <utility>

template <typename T>
struct GetIteratorImpl
{
    using iterator = decltype(std::begin(std::declval<T &>()));
    using reference = typename std::iterator_traits<iterator>::reference;
    using value_type = typename std::iterator_traits<iterator>::value_type;
    using pointer = typename std::iterator_traits<iterator>::pointer;
};

template <typename T>
using GetIterator = typename GetIteratorImpl<T>::iterator;

template <typename T>
using GetReference = typename GetIteratorImpl<T>::reference;

template <typename T>
using GetValueType = typename GetIteratorImpl<T>::value_type;

template <typename T>
using GetPointer = typename _GetIteratorImpl<T>::pointer;

To receive the return values of std::begin() and std::end(), so decltype() is used to specify the return type of std::begin(). However, this alone doesn’t resolve overloads. By specifying std::declval<>() as the argument for std::begin(), the template parameter T is indicated explicitly and the overloads can be resolved. Since the argument for std::begin() is an lvalue reference, you need to append & to std::declval<T &>().

Additionally, I’ve used std::iterator_traits<> to also obtain the element type, reference type to the element, and pointer to the element.

Example

It has limited use, but it can be utilized in situations where auto cannot be used, such as when you need an iterator or pointer as a member variable type in a class that uses templates.

template <typename T>
class SampleClass
{
        :
    GetIterator<T> iter_;
        :
};

C++

Posted by izadori