奇怪的行为?

new*_*use 3 c++ templates iterator typedef

可能重复:
我必须在何处以及为何要使用"template"和"typename"关键字?

几周前我(不得不:)成为一名C++开发人员(我以前有过一些经验,但不是太多,我更喜欢Java),试图学习所有重要的事情并尽可能高效地开发.如果我的问题完全愚蠢,那么请原谅.我有一个简单的示例模板类的问题:

template<typename T>
class SameCounter {
private:
    map<T,int> counted;
public:
    SameCounter(list<T> setup) {
        for(list<T>::iterator it = setup.begin(); it != setup.end(); it++) {
            counted[*it]++;
        }
    }
    map<T,int>::const_iterator& begin() { // line 25
        return counted.begin();
    }
    map<T,int>::const_iterator& end() {
        return counted.end();
    }
};

...
// using the class
Reader rdr;
rdr.Read();
SameCounter<char> sc(rdr.GetData());
Run Code Online (Sandbox Code Playgroud)

我在编译它时遇到一些错误:

Error   3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   d:\learn_cpp\examples\gyakorlas_1.cpp   25
Error   2   error C2143: syntax error : missing ';' before '&'  d:\learn_cpp\examples\gyakorlas_vizsga\gyakorlas_1.cpp  25

(both of them twice)
Run Code Online (Sandbox Code Playgroud)

我对它没有任何线索,也许我假设的模板有问题,因为如果我创建SameCounter作为普通类,那就完全没问题了.感谢您的帮助.

Kos*_*Kos 9

这应该可以帮到你:

typename map<T,int>::const_iterator& begin() {
    return counted.begin();
}
typename map<T,int>::const_iterator& end() {
    return counted.end();
}
Run Code Online (Sandbox Code Playgroud)

C++模板很棘手.T是一个模板参数,map<T, int>::const_iterator可能意味着不同的东西(类型名称,但是 - 比如静态成员......),这取决于你传递的是什么.

这就是为什么在模板中有时你需要明确你的意图并表明你实际上意味着" const_iterator是一种类型而我想要它的引用".关键字'typename'允许这样做.

请参阅:http://pages.cs.wisc.edu/~driscoll/typename.html


为了使您的代码更简单并避免减少需求typename,您可以从以下开始:

private:
    typedef std::map<T, int> MapType;
    MapType counted;
Run Code Online (Sandbox Code Playgroud)

然后就去吧

typename MapType::const_iterator &begin() {
Run Code Online (Sandbox Code Playgroud)

不幸的是,这typename仍然需要在这里,你需要进一步typedef typename为每个依赖类型将其从进一步的声明中删除(参见@ rhalbersma的回答).


在@ rhalbersma的评论之后,我还要强调你应该按值返回这些迭代器.返回对临时值的引用会导致未定义的行为,因为对象超出了范围,最终会出现"悬空引用".

所以做到:

typename MapType::const_iterator begin() {
Run Code Online (Sandbox Code Playgroud)

  • @ n3whous3:由于没有意识到这种模糊的C++特质,我几乎不会骂你.虽然这是我最喜欢的语言,但是当我看到它时,我会认出一个疣. (3认同)