Reputation: 964
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
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