如何为常量和非常量容器版本的迭代器定义类型

问题描述

考虑这个例子:

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;
}

它工作正常,如果您在容器类型中添加 const,则不再编译!

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

如何定义迭代器类型,它将用const/非常量容器类型编译。 我需要这样的东西:

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

解决方法

思路一:直接检查迭代器的类型。

实施:

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

想法 2:检查类型是否为 const 并使用此知识定义迭代器。

实施:

#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);
}