使用iterator_traits从迭代器对中推导出值类型

时间:2015-08-13 15:02:28

标签: c++11 iterator-traits

我有一个类型

typedef std::pair<ConstIterator, ConstIterator> Range;

typedef typename std::vector<T>::const_iterator ConstIterator;

我现在想使用std :: iterator_traits来推断Range的迭代器所指向的类型。

有人可以告诉我如何从Range类型的对象中实现这个目标吗?

3 个答案:

答案 0 :(得分:1)

您可以编写类型特征,部分专注于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>
{ };

答案 1 :(得分:0)

这将支持基于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;

请注意,const迭代器的值类型是非const值。

以上不是SFINAE友好的 - 一个工业品质的。

答案 2 :(得分:0)

您明确允许将模板特化添加到用户定义类型的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> {};
}