C++11 使用迭代器_特征从迭代器对推断值类型

C++11 使用迭代器_特征从迭代器对推断值类型,c++11,iterator-traits,C++11,Iterator Traits,我有一种 typedef std::pair<ConstIterator, ConstIterator> Range; typedef std::对范围; 与 typedef typename std::vector::const_迭代器; 现在我想使用std::iterator_traits来推断一个范围的迭代器所指向的类型 有谁能告诉我如何从类型范围的对象实现这一点吗?您可以编写一个类型特征,在对上部分专用: template <typename T> stru

我有一种

typedef std::pair<ConstIterator, ConstIterator> Range;
typedef std::对范围;

typedef typename std::vector::const_迭代器;
现在我想使用std::iterator_traits来推断一个范围的迭代器所指向的类型


有谁能告诉我如何从类型范围的对象实现这一点吗?

您可以编写一个类型特征,在
对上部分专用:

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>
{ };
模板
结构值类型{
使用type=typename std::iterator\u traits::value\u type;
};
模板
结构值类型
:值\类型
{ };

这将支持基于
对的范围和大多数iTerable:

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;
模板
结构值类型{
使用迭代器_type=decltype(std::begin(std::declval());
使用type=typename std::iterator\u traits::value\u type;
};
模板
结构值类型{
使用type=typename std::iterator\u traits::value\u type;
};
模板
使用value\u t=typename value\u type::type;
请注意,常量迭代器的值类型是非常量值


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

明确允许您为用户定义的类型向
std
命名空间添加模板专门化(感谢Barry的精确性!)。如果将
范围
修改为实际类型(而不仅仅是typedef),可以执行以下操作:

struct Range : std::pair<ConstIterator, ConstIterator> {
    using std::pair<ConstIterator, ConstIterator>::pair;
};

namespace std {
    template <>
    struct iterator_traits<Range> : iterator_traits<ConstIterator> {};
}

为什么不直接将专门化添加到
std::iterator_traits
?@Quentin您只能为用户定义的类型添加专门化。示例中的
及其组成部分都不是用户定义的类型。“那我就先走了。”巴里,谢谢你的回答。有一个问题,如果我想声明范围迭代器所指向的类型的变量,我将如何使用您的方法来实现这一点?我尝试了value\u type::type myVar;但我在表达式值_type::type myVar={}之后得到一个错误“@1v0无法判断”。可能缺少
typename
,肯定不需要
=
。只是
typename值_type::type var{}应该可以。可以添加别名,以便执行
value\u type\u t var{}
struct Range : std::pair<ConstIterator, ConstIterator> {
    using std::pair<ConstIterator, ConstIterator>::pair;
};

namespace std {
    template <>
    struct iterator_traits<Range> : iterator_traits<ConstIterator> {};
}
namespace std {
    template <class T>
    struct iterator_traits<Range<T>> : iterator_traits<T> {};
}