【问题标题】:C++ Using a class template argument as a template argument for another typeC++ 使用类模板参数作为另一种类型的模板参数
【发布时间】:2010-06-09 10:04:41
【问题描述】:

我在编写自己的 HashTable 时遇到了这个问题。一切正常,但是当我尝试将事物模板化时,它给了我错误。我重新创建了如下问题:

此代码有效:

typedef double Item;

class A
{
public:
    A()
    {
        v.push_back(pair<string, Item>("hey", 5.0));
    }

    void iterate()
    {
        for(Iterator iter = v.begin(); iter != v.end(); ++iter)
            cout << iter->first << ", " << iter->second << endl;
    }

private:
    vector<pair<string, double> > v;
    typedef vector< pair<string, double> >::iterator Iterator;
};

此代码没有:

template<typename ValueType>
class B
{
public:
    B(){}

    void iterate()
    {
        for(Iterator iter = v.begin(); iter != v.end(); ++iter)
            cout << iter->first << ", " << iter->second << endl;
    }

private:
    vector<pair<string, ValueType> > v;
    typedef vector< pair<string, ValueType> >::iterator Iterator;
};

错误信息: g++ -O0 -g3 -Wall -c -fmessage-length=0 -omain.o ..\main.cpp

..\main.cpp:50: 错误:输入std::vector&lt;std::pair&lt;std::string, ValueType&gt;, std::allocator&lt;std::pair&lt;std::string, ValueType&gt; &gt; &gt;' is not derived from typeB'

..\main.cpp:50: 错误:ISO C++ 禁止声明没有类型的“迭代器”

..\main.cpp:50: 错误:预期的 `;'在“迭代器”之前

..\main.cpp:在成员函数`void B::iterate()'中:

..\main.cpp:44: 错误:`Iterator' 未在此范围内声明

..\main.cpp:44: 错误:预期的 `;'在“迭代”之前

..\main.cpp:44: 错误:`iter' 未在此范围内声明

有人知道为什么会这样吗?谢谢!

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    这在 C++ 中称为“依赖名称”。在您的第二个代码 sn-p 中,您说:

    typedef vector< pair<string, ValueType> >::iterator Iterator;
    

    而你应该说:

    typedef typename vector< pair<string, ValueType> >::iterator Iterator;
    

    每当您看到“不是派生...”的错误时,typename 就可以解决问题。 一般来说,这个想法是编译器不知道迭代器是类型还是变量,因为它不知道是什么

    vector< pair <string, ValueType> >
    

    是,因为它取决于 ValueType。

    (恐怕我在这里没有使用正确的术语,但想法是正确的)

    【讨论】:

    • 不应该是:typedef typename vector >::iterator Iterator; ?
    • @Tomek: pair&lt;string, ValueType&gt; 只能是一个类型,因为pair 是一个类模板。所以编译器知道它是一个类型,没有必要用typename消除歧义。
    • Tomek:没有它,它构建得很好,所以我想它很好。你没有在这里说例如 pair::first_type,所以你不需要那个类型名。
    【解决方案2】:

    感谢它的工作,现在一切都有意义了!

    我不想使用 typedef,我也可以像这样使用 typename:

    for( typename list<pair<string, ValueType> >::const_iterator itr = v.begin(); itr != v.end() ; ++itr){
    {
    //code
    }
    

    【讨论】:

    • 你最好 typedef 它,因为它通常是正确的做事方式,而且你可能会养成不 typedef 的习惯,这不太好)
    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多