是否可以从任意迭代器(C ++)获取值类型?

时间:2009-07-10 00:36:44

标签: c++ templates

我有一个班级

template <typename Iterator, typename Value>
class Foo {
 public:
  Foo(const Iterator& it) { ... }
  ...
 private:
   map<Value, int> m_;
  }
};

有没有办法摆脱模板中的Value?迭代器可能是也可能不是STL迭代器,但它保证*它的类型是值。

我知道STL迭代器的iterator_traits<T>::value_type,但是想知道是否有任何方法可以自动为任意Iterator类型获取Value类型?

我正在考虑的一个技巧 - 比方说,我们有一个助手类

template <typename Iterator, typename Value>
class Bar {
 public:
  Bar(const Iterator& dummy_iterator, const Value& dummmy_value) {}
  ...
};

然后,如果我们将Bar实例化为Bar(它,* it),则在Bar中将知道Value的类型。但我找不到将Bar与Foo结合起来的好方法。

3 个答案:

答案 0 :(得分:18)

任何迭代器都应提供iterator_traits<Iterator>::value_type。如果没有,则它不是迭代器。 ISO C ++ 2003 24.3.1 [lib.iterator.traits]“Iterator traits”:

  

仅以术语实现算法   对于迭代器,通常需要   确定价值和差异   与特定对应的类型   迭代器类型。因此,它是   要求Iterator是类型   迭代器,类型

iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::iterator_category
     

被定义为迭代器   差异类型,价值类型和   迭代器类别。

除此之外,没有获得任意C ++表达式的通用方法。 C ++ 0x将通过提供decltype来纠正它。

答案 1 :(得分:1)

对不起。摆脱Value的正确方法是按照建议使用iterator_traits

如果你的非STL迭代器是一个裸指针,那么你可以免费获得正确的iterator_traits typedef。否则,非STL迭代器类必须定义正确的typedef。

有关详细信息,请参阅iterator traits documentation

答案 2 :(得分:1)

至于获取迭代器的值类型以前的答案是正确的。

但还有更多。你想到的诀窍不适合上课。如果Bar的功能如下:

template <typename Iterator, typename Value>
void bar(const Iterator& dummy_iterator, const Value& dummmy_value) {}

然后类型推导将适用于bar(it, *it),您将拥有bar内的值类型。 (但请记住,要使用这个技巧,你仍然必须有一个不可控制的迭代器,这并不总是好的 - 那么如何处理空序列呢?)

使用类Bar,您必须手动提供模板参数IteratorValue,因为类没有类型推断,使用Bar(it, *it)将无法编译。