1

我有一个类型

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

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

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

谁能告诉我如何从 Range 类型的对象中实现这一点?

4

3 回答 3

1

您可以编写一个类型特征,部分专门用于 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>
{ };
于 2015-08-13T15:09:34.743 回答
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;

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

上述内容对 SFINAE 不友好——应该是工业质量的。

于 2015-08-13T15:10:05.660 回答
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> {};
}
于 2015-08-13T15:16:27.193 回答