c++ - 检查/修改迭代器 "constness"

标签 c++ templates iterator constants

我有两个半密切相关的问题。给定一个作为模板参数传递的 STL 迭代器类型:

  1. 如何判断类型对应的是常量迭代器还是非常量迭代器?
  2. 替代 1.,如何强制(例如使用 enable_if)此类型对应于非常量迭代器?
  3. 如何从非常量迭代器获取迭代器的 const- 版本(反之亦然)? [ 注意:已在 this post 中回答;毫不奇怪,你不能。 ]

这个问题来自哪里:

我写了一个小类来促进 vector 上的算术/关系/代数运算( vector 我的意思是一维固定大小的数据,而不是 STL vector )。我没有强加一个特定的数据容器,而是定义了一个接口(interface)并派生了几个可能的容器,这些容器基本上“包装”了各种存储数据的方式。其中一个容器是 STL 迭代器的包装器,我在使用它时遇到了一些麻烦。

最佳答案

问题 1:

您可以使用以下类型特征:

template<typename T, typename = void>
struct is_const_iterator : std::false_type { };

template<typename T>
struct is_const_iterator<T,
    typename std::enable_if<
        std::is_const<
            typename std::remove_pointer<
                typename std::iterator_traits<T>::pointer
                >::type
            >::value
        >::type> : std::true_type { };

这是一个演示:

#include <type_traits>
#include <iterator>
#include <list>
#include <vector>

template<typename T, typename = void>
struct is_const_iterator : std::false_type { };

template<typename T>
struct is_const_iterator<T,
    typename std::enable_if<
        std::is_const<
            typename std::remove_pointer<
                typename std::iterator_traits<T>::pointer
                >::type
            >::value
        >::type> : std::true_type { };

int main()
{
    typedef std::list<int>::iterator LI;
    typedef std::list<int>::const_iterator CLI;
    static_assert(is_const_iterator<LI>::value, "!"); // Fires
    static_assert(is_const_iterator<CLI>::value, "!"); // Does not fire

    typedef std::vector<int>::iterator VI;
    typedef std::vector<int>::const_iterator CVI;
    static_assert(is_const_iterator<VI>::value, "!"); // Fires
    static_assert(is_const_iterator<CVI>::value, "!"); // Does not fire
}

这是一个 live example .

问题 2:

有了上面的类型特征,这就变得简单了。假设您有一个要约束的函数模板 foo(),以便它只接受非 const 迭代器:

template<typename It,
    typename std::enable_if<!is_const_iterator<It>::value>::type* = nullptr>
void foo(It i)
{
    // Does something with i...
}

还有一个简单的演示程序:

int main()
{
    std::vector<int> v;
    foo(v.begin()); // OK
    foo(v.cbegin()); // ERROR!
}

这是一个 live example .

关于c++ - 检查/修改迭代器 "constness",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16498674/

相关文章:

c++ - 是否可以安全地假设 64 位指针中的 16 位高位(2 位对我来说足够)未设置?

c++ - 在屏幕上用 SFML 编写文本输入

java - 使用迭代器的 ArrayList 的不同值的 ArrayList

PHP7 重命名迭代器内目录中的所有文件(Windows 10)64 位 XAMPP

c++ - 如何在 C++ 中的 vector 中插入多个值?

c++ - 将 argv 与函数一起使用时出错

django - django中是否有任何tile类型的概念

c++ - 在 C++ 中将函数作为参数传递给模板?

c++ - 在编译时加密/混淆字符串文字

javascript - 从对象中获取属性值并将其分配给 JavaScript 中的变量