我很确定我已经阅读了编译器无法在SO上某处处理此代码的原因,但是,经过几个小时的搜索后,我仍然无法找到它。以下是相关代码:
#include <iostream>
template <typename T>
class base
{
};
class derived : base<derived::myStruct>
{
public:
struct myStruct
{
};
};
int main ()
{
return 0;
}
问题是解析器在解析base<derived::myStruct>
之前首先尝试生成derived
特化,因此,我收到此错误:“错误C2065:'myStruct':未声明的标识符”。作为一个愚蠢的伎俩,我注意到如果我在struct myStruct;
之上预先声明class derived
,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中的一个错误......
答案 0 :(得分: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;
}
答案 1 :(得分:1)
在C ++中,只能在定义名称后引用名称。由于derived
显然尚未定义,当您引用嵌套在derived
内的类来定义基类时,这不起作用。在访问它们之后声明的事物的异常是在类定义中定义的成员的函数体:这些被视为它们实际上是在类定义之后定义的。
答案 2 :(得分:1)
解决方法是在myStruct
之外声明derived
。
#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
也是一个模板类,具有相同的模板参数(或只是一个子集),您可以通过它们。 / p>