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

Using iterator_traits to deduce value type from pair of iterators

我有一个类型

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

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

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

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

你可以写一个类型特征,部分特化在 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;

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

以上内容对 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> {};
}