如何检测类型是迭代器还是const_iterator

Jan*_*cek 14 c++ templates iterator stl metaprogramming

我想知道,如果有一种方法可以在编译时检查某个迭代器类型的类型T是否为const_iterator.迭代器和const迭代器之间的迭代器定义的类型(value_type,pointer,...)有什么不同吗?

我想实现这样的目标:

typedef std::vector<int> T;

is_const_iterator<T::iterator>::value       // is false
is_const_iterator<T::const_iterator>::value // is true
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 22

C++ 03解决方案:

由于答案似乎都没有,这是我与GCC合作的尝试:

template<typename T>
struct is_const_pointer { static const bool value = false; };

template<typename T>
struct is_const_pointer<const T*> { static const bool value = true; };

template <typename TIterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<TIterator>::pointer pointer;
    static const bool value = is_const_pointer<pointer>::value;
};
Run Code Online (Sandbox Code Playgroud)

例:

int main()
{
    typedef std::vector<int>::iterator it_type;
    typedef std::vector<int>::const_iterator const_it_type;

    std::cout << (is_const_iterator<it_type>::value) << std::endl;
    std::cout << (is_const_iterator<const_it_type>::value) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
1
Run Code Online (Sandbox Code Playgroud)

在线演示:http://ideone.com/TFYcW

  • 我选择了你的答案,因为你的解决方案使用了std :: iterator_traits <>类 (3认同)
  • 当`std :: iterator_traits <I> :: pointer`是代理类类型时不起作用.但如果有一个解决方案,它将不得不使用一些非常讨厌的SFINAE. (3认同)

Sim*_*ter 5

至少在gcc上工作的一种方法是通过引用 typedef:

struct true_type { };
struct false_type { };

template<typename T>
struct is_const_reference
{
    typedef false_type type;
};

template<typename T>
struct is_const_reference<T const &>
{
    typedef true_type type;
};

template<typename T>
struct is_const_iterator
{
    typedef typename is_const_reference<
        typename std::iterator_traits<T>::reference>::type type;
};
Run Code Online (Sandbox Code Playgroud)

您可以使用验证它是否有效

inline bool test_internal(true_type)
{
    return true;
}

inline bool test_internal(false_type)
{
    return false;
}

template<typename T>
bool test(T const &)
{
    return test_internal(typename is_const_iterator<T>::type());
}

bool this_should_return_false(void)
{
    std::list<int> l;
    return test(l.begin());
}

bool this_should_return_true(void)
{
    std::list<int> const l;
    return test(l.begin());
}
Run Code Online (Sandbox Code Playgroud)

在具有足够高的优化级别的情况下,最后两个函数应分别减少到return false;return true;.至少他们为我做了.


Mik*_*han 5

使用C++11,新的标准头<type_traits>提供了std::is_const<T>,因此Nawaz的解决方案可以简化:

template<typename Iterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<Iterator>::pointer pointer; 
    static const bool value = 
        std::is_const<typename std::remove_pointer<pointer>::type>::value;
};
Run Code Online (Sandbox Code Playgroud)


Leo*_*sky 5

C ++ 11

template<class IT, class T=decltype(*std::declval<IT>())>    
constexpr bool  
is_const_iterator() {   
        return  ! std::is_assignable <
                decltype( *std::declval<IT>() ),
                T   
        >::value;
}
Run Code Online (Sandbox Code Playgroud)

  • 这涉及到const_iterator的constness的核心-您无法分配从取消引用迭代器返回的内容。这可能是适用于vector &lt;bool&gt;等奇数球的唯一答案。(当然,它不会检查它是否是迭代器,还是可取消引用的,但是OP假定它是某种迭代器。但是将其称为“ is_const_iterator”,它应该同时检查const-ness和迭代器...) (2认同)