4

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

#include <iostream>

template <typename T>
class base
{
};

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

int main ()
{
    return 0;
}

问题是解析器首先尝试base<derived::myStruct>在 parsing 之前生成专业化derived,因此,我收到此错误:“error C2065: 'myStruct' : undeclared identifier”。struct myStruct;作为一个愚蠢的技巧,我注意到如果我在上面预先声明 VS2010 就会停止抱怨class derived。在我看来,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 能够抛出预期的错误,所以,我猜上面是 VS2010 中的一个错误......

4

3 回答 3

2

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

template <typename T>
class base
{
};

class middle
{
public:
    struct myStruct
    {
    };
};

class derived : public middle, base<middle::myStruct>
{
};

int main ()
{
    return 0;
}
于 2012-11-17T00:26:00.313 回答
1

一种解决方法是myStructderived.

#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也是模板类,具有相同的模板参数(或只是一个子集),您可以通过这些模板类。

于 2012-11-17T00:24:51.590 回答
1

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

于 2012-11-17T00:11:43.150 回答