101*_*010 11 c++ iterator type-traits c++11 c++14
我正在尝试编写一个is_iterator<T>
类型特征.凡当T
是一个迭代器类型is_iterator<T>::value == true
,否则是is_iterator<T>::value == false
.
到目前为止我尝试了什么:
template <class, class Enable = void>
struct is_iterator : std::false_type {};
template <typename T>
struct is_iterator<T, typename std::enable_if<std::is_pointer<typename
std::iterator_traits<T>::pointer>::value>::type> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)
问:是否有更合适的方式来定义is_iterator
类型特征而不是上面显示的类型特征?
正如我在评论中所说,这里介绍的解决方案依赖iterators_traits
于某些实现中的非便携属性.根据C++ 03和C++ 11标准,iterator_traits
仅为迭代器(以及指针的特殊情况)定义,因此任何其他用途都是未定义的行为.具体而言,使用iterator_traits<T>::pointer
在SFINAE背景不能保证工作,因为实例iterator_traits<T>
会参考T::value_type
,T::pointer
,T::iterator_category
等,并且这种情况发生"立即语境"里SFINAE不适之外.
C++ 14 将修复本应修复的问题(它发生在C++ 14之后的DR 2408),但对于C++ 11,定义的安全方法is_iterator
是编写一个特征来检查所有必需的操作迭代器必须定义.所有迭代器都需要支持的唯一操作是operator*
增量前和后增量.不幸的是,可能存在定义那些不是有效迭代器的操作的类型,因此编写正确的特征非常困难.
std::iterator_traits<T>::pointer
如果是不是指针的类型,例如 if ,则检查失败T = std::ostream_iterator<U>
。
我认为更好的测试可能是是否std::iterator_traits<T>::iterator_category
是std::input_iterator_tag
或派生类型,或std::output_iterator_tag
。
template <class, class Enable = void> struct is_iterator : std::false_type {};
template <typename T>
struct is_iterator
<T,
typename std::enable_if<
std::is_base_of<std::input_iterator_tag, typename std::iterator_traits<T>::iterator_category>::value ||
std::is_same<std::output_iterator_tag, typename std::iterator_traits<T>::iterator_category>::value
>::type>
: std::true_type {};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1982 次 |
最近记录: |