我有一个类型
typedef std::pair<ConstIterator, ConstIterator> Range;
和
typedef typename std::vector<T>::const_iterator ConstIterator;
我现在想使用 std::iterator_traits 来推断 Range 的迭代器指向的类型。
谁能告诉我如何从 Range 类型的对象中实现这一点?
我有一个类型
typedef std::pair<ConstIterator, ConstIterator> Range;
和
typedef typename std::vector<T>::const_iterator ConstIterator;
我现在想使用 std::iterator_traits 来推断 Range 的迭代器指向的类型。
谁能告诉我如何从 Range 类型的对象中实现这一点?
您可以编写一个类型特征,部分专门用于 a pair
:
template <typename T>
struct value_type {
using type = typename std::iterator_traits<T>::value_type;
};
template <typename T>
struct value_type<std::pair<T, T>>
: value_type<T>
{ };
这将支持您pair
的基于范围和大多数可迭代对象:
template<class R>
struct value_type {
using iterator_type = decltype( std::begin(std::declval<R>()) );
using type=typename std::iterator_traits<iterator_type>::value_type;
};
template<class It>
struct value_type<std::pair<It,It>> {
using type=typename std::iterator_traits<It>::value_type;
};
template<class X>
using value_t = typename value_type<X>::type;
请注意,常量迭代器的值类型是非常量值。
上述内容对 SFINAE 不友好——应该是工业质量的。
您被明确允许将模板std
特化添加到用户定义类型的命名空间(感谢 Barry 的精确度!)。如果你将你改造Range
成一个实际的类型(不仅仅是一个 typedef),你可以这样做:
struct Range : std::pair<ConstIterator, ConstIterator> {
using std::pair<ConstIterator, ConstIterator>::pair;
};
namespace std {
template <>
struct iterator_traits<Range> : iterator_traits<ConstIterator> {};
}
当您稍微增强Range
一下时,我希望这会演变成:
namespace std {
template <class T>
struct iterator_traits<Range<T>> : iterator_traits<T> {};
}