user3324131
user3324131

Reputation: 964

How to define a type for an iterator for a const and non-const container version

Consider this example:

template <typename T> struct A {
    using Iter = typename T::iterator;
    Iter iter;
    A(T& cont) {
        iter = cont.begin();
    }
    typename Iter::reference value() { return *iter; }
};

void f(std::vector<int>& v) {
    A a(v);
    a.value() = 10;
}

It work fine, buy if you add const to container type, it's no more compile!

int g(const std::vector<int>& v) {
    A a(v); // ERROR
    return a.value();
}

How to define iterator type, that will compile with const/non-const container type. I need something like that:

using Iter = decltype(T::begin());

Upvotes: 1

Views: 322

Answers (1)

SergeyA
SergeyA

Reputation: 62613

Idea 1: check the type of the iterator directly.

Implementation:

   using Iter = decltype(std::declval<T>()::begin());

Idea 2: check if the type is const and define iterator using this knowledge.

Implementation:

#include <vector>
#include <type_traits>

template <typename T> struct A {
    using Iter = std::conditional_t<
                        std::is_same_v<std::remove_const_t<T>, T>, typename T::iterator, typename T::const_iterator
                                   >;
    Iter iter;
    A(T& cont) {
        iter = cont.begin();
    }
};

void f(const std::vector<int>& v) {
    A a(v);
}


void f1(std::vector<int>& v) {
    A a(v);
}

Upvotes: 3

Related Questions