以下代码段无法使用Visual Studio 2010进行编译,但GCC喜欢它:
namespace Test {
class Baz;
// Adding class Bar; here and removing the class below makes it work
// with VC++, but it should work like this, shouldn't it?
void Foo (Baz& b, class Bar& c);
}
namespace Test {
class Bar
{
// Making this method non-template works
template <typename T>
static void Lalala ()
{
}
};
}
int main ()
{
}
我在这里做些蠢事还是这是一个有效的编译器错误?我得到的错误是:
error C2888: 'void Bar::Foo(void)' : symbol cannot be defined within namespace 'Test'
它使用GCC 4.5.1进行编译:http://ideone.com/7sImY
[编辑]为了清楚起见,我想知道这是否是有效的C ++(如果是这样,为什么不呢) - 编译它的变通方法很好但不是这个问题的一部分。
答案 0 :(得分:2)
好吧,我也在codepad.org尝试了它并且它编译了,但我不确定它是否应该(不精通C ++编译器功能)!
击>
解决方法:也可以转发声明Bar
,或者在制作Bar
之前必须定义Foo
。换句话说,这在MSVC中编译:
namespace Test
{
class Baz;
class Bar;// also forward-declare Bar
void Foo (Baz& b, class Bar& c);
}
namespace Test
{
class Bar
{
template <typename T>
static void Foo ()
{
}
};
}
int main(void)
{
return 0;
}
<强>更新强> 我认为这可能已经是向微软报告的错误...这看起来非常接近:http://connect.microsoft.com/VisualStudio/feedback/details/99218/invalid-error-c2888-when-a-class-is-defined-after-it-is-declared
Microsoft引用的解决方法:
A stand-alone forward declaration consists of an elaborated type specifier followed by a semicolon.
insert the declaration
class C2888;
before the declaration of foo(C2888o, C2888).
答案 1 :(得分:1)
可能是编译错误。
更改参数的顺序将改变编译结果。
namespace Test {
void Foo (class Bar& b, class Baz& c) - will compile.
}
答案 2 :(得分:1)
我认为代码格式正确。但事实证明,确保标准中没有任何内容与使用相矛盾。
C ++ 11标准中的一些相关引用:
3.3.2 p6:
首先在 elaborated-type-specifier 中声明的类的声明点如下:
3.4.4 p2:
如果 elaborated-type-specifier 没有嵌套名称说明符,除非elaborated-type-specifier出现在具有以下形式的声明中: class-key attribute-specifier-seq opt identifier
;
根据3.4.1查找标识符,但忽略已声明的任何非类型名称。 ...如果引入了 elaborated-type-specifier class-key 并且此查找找不到先前声明的 type-name ,或者 elaborated-type-specifier 出现在具有以下形式的声明中: class-key attribute-specifier-seq opt identifier;
elaborated-type-specifier 是一个声明,它引入了 class-name ,如3.3.2所述。
7.1.6有一些语法定义确定 elaborated-type-specifier 在语法上可以是类型说明符。 7.1确定类型说明符在语法上可以是 decl-specifier ,它是在函数 parameter-declaration (8.3.5)。
答案 3 :(得分:-2)
class Bar
构造是错误的。你是否是一个没有使用typedef struct { /* members */ } Foo
的C程序员?
Anywho,你需要在测试中定义Bar和Baz:
namespace Test {
class Bar;
class Baz;
};
在声明函数参数时,请删除class
,struct
,union
和enum
个关键字。
通过这种修改,它可以在g ++ 4.6中完全编译。