2009-07-10 48 views
14

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

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

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

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

一招我在想 - 比方说,我们有一个辅助类

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

然后如果我们实例酒吧,酒吧(它,*它),值的类型将里面酒吧是已知的。但是我找不到将Bar与Foo结合的好方法。

回答

18

任何迭代器应该提供iterator_traits<Iterator>::value_type。如果不是,那么它不是迭代器。 ISO C++ 2003 24.3.1 [lib.iterator.traits]“迭代特征”:

为了实现算法仅在术语迭代 ,它通常需要 确定该值和差 类型对应于一个特定的 迭代器类型。因此,它是 必需的:如果Iterator是一个迭代的 类型,类型

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

被定义为迭代器的 差类型,值和类型迭代 类别,分别。

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

+0

谢谢,所述参考ISO C++标准是有帮助的。 – 2009-07-10 18:10:50

1

对不起。根据您的建议,摆脱Value的正确方法是使用iterator_traits

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

查看iterator traits documentation了解更多信息。

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)会没有编译。

+0

谢谢!我想到了使用bar作为函数的相同之处,但是也许我错过了一些东西。 – 2009-07-10 18:12:42

相关问题