我有以下的代码,基本上是这样的:
class foo {
public:
void method();
};
void foo::foo::method() { }
在foo::method的定义前面,我不小心多加了一个foo::。在使用g++(ver 4.2.3)编译时,这段代码没有警告,但在使用Visual Studio 2005时会出错。我没有一个名为foo的命名空间。
哪个编译器是正确的?
我有以下的代码,基本上是这样的:
class foo {
public:
void method();
};
void foo::foo::method() { }
在foo::method的定义前面,我不小心多加了一个foo::。在使用g++(ver 4.2.3)编译时,这段代码没有警告,但在使用Visual Studio 2005时会出错。我没有一个名为foo的命名空间。
哪个编译器是正确的?
3.4/3
。在类中查找是根据成员名称定义的 - 因此需要这句话才能使问题中的情况有效。请注意,Comeau在拒绝有效代码struct A { void f() { A::A a; } };
时是错误的 :) 如果您在答案中包含该引用,我会给您点赞 xD - Johannes Schaub - litbKrugar 在这里给出了正确的答案。每次被找到的名称都是注入的类名。
以下是一个示例,至少说明编译器添加注入类名的一个原因:
namespace NS
{
class B
{
// injected name B // #1
public:
void foo ();
};
int i; // #2
}
class B // #3
{
public:
void foo ();
};
int i; // #4
class A :: NS::B
{
public:
void bar ()
{
++i; // Lookup for 'i' searches scope of
// 'A', then in base 'NS::B' and
// finally in '::'. Finds #4
B & b = *this; // Lookup for 'B' searches scope of 'A'
// then in base 'NS::B' and finds #1
// the injected name 'B'.
}
};
如果没有注入的名称,当前查找规则最终会到达'A'的封闭范围,并找到'::B'而不是'NS::B'。因此,在A中希望引用基类时,我们需要到处使用"NS::B"。
注入的名称在模板中也会被使用,在类模板内部,注入的名称提供了模板名称和类型之间的映射:
template <typename T>
class A
{
// First injected name 'A<T>'
// Additional injected name 'A' maps to 'A<T>'
public:
void foo ()
{
// '::A' here is the template name
// 'A' is the type 'A<T>'
// 'A<T>' is also the type 'A<T>'
}
};
你包含的其他模块中有命名空间foo吗(而你只是不知道)?否则,这是不正确的。我不确定为什么g++会允许这样。