【问题标题】:Undefined template argument for base class基类的未定义模板参数
【发布时间】:2012-11-17 00:05:13
【问题描述】:

我很确定我已经阅读了编译器无法在 SO 上的某处处理此代码的原因,但是,经过几个小时的搜索,我仍然找不到它。以下是相关代码:

#include <iostream>

template <typename T>
class base
{
};

class derived : base<derived::myStruct>
{
public:
    struct myStruct
    {
    };
};

int main ()
{
    return 0;
}

问题是解析器在解析derived 之前首先尝试生成base&lt;derived::myStruct&gt; 特化,因此,我收到此错误:“错误C2065:'myStruct':未声明的标识符”。作为一个愚蠢的技巧,我注意到如果我在class derived 上方预先声明struct myStruct;,VS2010 就会停止抱怨。在我看来,myStruct 应该绑定在 derived 内,并且这段代码应该会抛出同样的错误:

#include <iostream>

template <typename T>
class base
{
};

struct myStruct;

class derived : base<derived::myStruct>
{
public:
    struct myStruct
    {
    };
};

int main ()
{
    return 0;
}

更新:gcc-4.5.1可以throw the expected error,所以,我猜上面是VS2010的一个bug...

【问题讨论】:

    标签: c++ templates inheritance nested


    【解决方案1】:

    derived::myStruct 在这一点上只是一个不完整的类型。您的第二个示例也不应该工作,不幸的是 MSVC 编译器接受了很多格式错误的模板代码。一种解决方法是使用中间类来确保类型是完整的:

    template <typename T>
    class base
    {
    };
    
    class middle
    {
    public:
        struct myStruct
        {
        };
    };
    
    class derived : public middle, base<middle::myStruct>
    {
    };
    
    int main ()
    {
        return 0;
    }
    

    【讨论】:

    • 中产阶级服务的目的是什么,为什么不只有 myStruct(正如我在回答中提出的那样)?
    • 啊,我明白了,你避免了 typedef。但是仅仅为此使用多重继承似乎有点奇怪:)
    • @AmbrozBizjak:我认为它也会保留继承模式,但我不确定这是为了什么。
    【解决方案2】:

    一种解决方法是在derived 之外声明myStruct

    #include <iostream>
    
    template <typename T>
    class base
    {
    };
    
    struct derived_myStruct
    {
    };
    
    class derived : base<derived_myStruct>
    {
    public:
        typedef derived_myStruct myStruct;
    };
    
    int main ()
    {
        return 0;
    }
    

    在更复杂的情况下,derived 是一个模板类,derived_myStruct 也将是一个模板类,具有相同的模板参数(或只是一个子集),您可以通过这些参数。

    【讨论】:

    • 看起来这是 C++ 中这个特定设计问题的最佳解决方案。我不喜欢不能嵌套相关类型,但似乎没有办法。
    【解决方案3】:

    在 C++ 中,您只能在定义名称后引用它们。由于derived 显然还没有定义,当您引用嵌套在derived 中的类来定义基类时,这是行不通的。事物在被访问后被声明的例外是在类定义中定义的成员的函数体:这些被视为实际上是在类定义之后定义的。

    【讨论】:

    • 那么,我该如何绕过这个限制呢?我绝对记得有一个建议的解决方法,而我上面提供的解决方法,从我的角度来看,根本不应该工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多