【问题标题】:How to define a type for an iterator for a const and non-const container version如何为 const 和非常量容器版本的迭代器定义类型
【发布时间】:2021-09-05 09:40:16
【问题描述】:

考虑这个例子:

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/non-const 容器类型一起编译。 我需要这样的东西:

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

【问题讨论】:

  • 你在用这个迭代器做什么?你要修改它指向的东西吗?如果没有,只需使用 T::const_iterator 并始终获取 const 的迭代器。
  • 如果容器不是 const,迭代器必须允许修改
  • @NathanOliver 我编辑了帖子

标签: c++ templates stl


【解决方案1】:

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

实施:

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

【讨论】:

  • Idea 1 不是由 gcc 10 编译的,但是idea 2 有效!谢谢你!
  • @user3324131 抱歉,有一个错字,想法 1 是 decltype(std::declval&lt;T&gt;().begin());。这应该有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2016-04-05
  • 2011-06-09
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
相关资源
最近更新 更多