简单,请看这段代码:
namespace B
{
struct A{ int i; } ;
A getA(int i);
}
// ____ if I'll delete '::' then program successfull compiled.
// /
::B::A ::B::getA(int i){ ::B::A a = {i}; return a;}
#include <cstdio>
int main()
{
::B::A a = ::B::getA(2);
printf("%d\n", a.i);
}
错误列表VS2010:
1>main.cpp(94): error C3083: 'B': the symbol to the left of a '::' must be a type
1>main.cpp(94): error C2039: 'getA' : is not a member of 'B::A'
1>main.cpp(88) : see declaration of 'B::A'
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>main.cpp(94): error C2440: 'return' : cannot convert from 'B::A' to 'int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>main.cpp(94): error C2617: 'getA' : inconsistent return statement
1>main.cpp(94) : see declaration of 'getA'
Gcc.4.8.1错误列表(from ideone.com):
prog.cpp:10:1: error: ‘B’ in ‘struct B::A’ does not name a type
::B::A ::B::getA(int i){ ::B::A a = {i}; return a;}
^
问:这是一个错误,或者我不明白?
答案 0 :(得分:8)
通常,除了需要分隔令牌之外,令牌之间的空格没有任何意义。所以这个:
::B::A ::B::getA(...)
相当于
::B::A::B::getA(...)
要表明它们是两个单独的限定名,请在函数名称周围使用括号:
::B::A (::B::getA)(...)
或者,如您所说,删除顶级限定符(尽管如果您在范围内有其他名为B
的内容,则可能会导致混淆。)
答案 1 :(得分:2)
这是编译器看到的代码与您认为的不同的情况。那些难以调试,因为错误消息似乎是无关紧要的,而且几乎是随机的。
问题是编译器会忽略::B::A
和::B::getA
之间的空格,因此它认为你正在谈论函数::B::A::B::getA()
。您无法定义该函数(编译器的事物视图中没有返回类型)或调用该函数(基于稍后出现的函数体)并不重要。 。编译器没有足够的知识来解决歧义。相反,它意识到它从未看到类型::B::A::B
的声明,并且给出了错误消息。