我有一个班级
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结合起来的好方法。
答案 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
,您必须手动提供模板参数Iterator
和Value
,因为类没有类型推断,使用Bar(it, *it)
将无法编译。