如何定义is_iterator类型trait? [英] How to define is_iterator type trait?
问题描述
-
我尝试编写
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 {};
Q:是否有更适当的方法来定义 is_iterator
类型特征?
正如我在评论中所说,这里提出的解决方案依赖于在一些实现中 iterators_traits
的非便携性属性。根据C ++ 03和C ++ 11标准, iterator_traits
只定义为迭代器(和指针的特殊情况),所以任何其他用途是未定义的行为。特别地,在SFINAE上下文中使用 iterator_traits< T> :: pointer
不能保证工作,因为实例化 iterator_traits< T>
将引用 T :: value_type
, T :: pointer
, T: :iterator_category
等,并且发生在不适用SFINAE的立即上下文之外。
C ++ 14 <修复了应该修复它(它发生在C ++ 14之后的 DR 2408 )但对于C ++ 11,定义 is_iterator
的安全方法是写一个trait,该trait检查迭代器必须定义的所有必需的操作。所有迭代器需要支持的唯一操作是 operator *
以及前和后递增。不幸的是,可能有类型定义那些不是有效迭代器的操作,所以编写正确的trait是很难的。
I'm trying to code a
is_iterator<T>
type trait. Where whenT
is an iterator typeis_iterator<T>::value == true
otherwise isis_iterator<T>::value == false
.What I tried so far:
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 {};
Q: Is there a more proper way to define a is_iterator
type trait than the one displayed above?
As I said in comments, the solutions presented here rely on non-portable properties of iterators_traits
in some implementations. According to the C++03 and C++11 standards, iterator_traits
is only defined for iterators (and the special case of pointers) so any other use is undefined behaviour. Specifically, using iterator_traits<T>::pointer
in a SFINAE context isn't guaranteed to work, because instantiating iterator_traits<T>
will refer to T::value_type
, T::pointer
, T::iterator_category
etc. and that happens outside the "immediate context" where SFINAE doesn't apply.
C++14 will fix that was supposed to fix that (it happened post-C++14 with DR 2408), but for C++11 the safe way to define is_iterator
is to write a trait that checks for all the required operations an iterator must define. The only operations that all iterators are required to support are operator*
and pre- and post-increment. Unfortunately, there can be types that define those operations which are not valid iterators, so writing a correct trait is quite hard.
这篇关于如何定义is_iterator类型trait?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!