命名空间内的友元函数声明/定义
考虑一个命名空间内的类.类的定义声明了一个友元函数.
Consider a class inside a namespace. The definition of the class declares a friend function.
namespace Foo
{
class Bar
{
friend void baz();
};
}
据我所知,这应该将 baz()
声明为最内层封闭命名空间的成员,即 Foo
.
This should, based on what I know, declare baz()
as a member of the innermost enclosing namespace, i.e. Foo
.
因此,我希望 baz()
的以下定义是正确的:
Therefore, I expected the following definition for baz()
to be correct:
void Foo::baz() { }
但是,GCC (4.7) 给了我一个错误.
However, GCC (4.7) gives me an error.
error: ‘void Foo::baz()’ should have been declared inside ‘Foo’
几种解决方案似乎都有效:
Several solutions seem to work:
在类外声明
baz()
.
namespace Foo
{
void baz();
class Bar
{
friend void baz();
};
}
在命名空间内定义baz()
.
namespace Foo
{
class Bar
{
friend void baz();
};
}
...
namespace Foo
{
void baz() { }
}
使用 -ffriend-injection
标志编译,消除错误.
Compile with the -ffriend-injection
flag, which eliminates the error.
这些解决方案似乎与我所知道的 C++ 中声明/定义的一般规则不一致.
These solutions seem to be inconsistent with the general rules of declaration/definition in C++ I know.
为什么我必须声明 baz()
两次?
为什么该定义仅在命名空间内是合法的,而在范围解析运算符中是非法的?
为什么flag会消除错误?
Why do I have to declare baz()
twice?
Why is the definition otherwise only legal inside a namespace, and illegal with the scope resolution operator?
Why does the flag eliminate the error?
推荐答案
为什么我必须声明 baz() 两次?
Why do I have to declare baz() twice?
因为友元声明没有提供命名空间中函数的可用声明.它声明,如果在该命名空间中声明了该函数,它将是友元;如果您要在一个类中定义一个友元函数,那么它可以通过依赖于参数的查找(但不是其他方式)可用,就好像它是在命名空间中声明的一样.
Because the friend declaration doesn't provide a usable declaration of the function in the namespace. It declares that, if that function is declared in that namespace, it will be a friend; and if you were to define a friend function inside a class, then it would be available via argument-dependent lookup (but not otherwise) as if it were declared in the namespace.
为什么定义只在命名空间内是合法的,而在范围解析运算符中是非法的?
Why is the definition otherwise only legal inside a namespace, and illegal with the scope resolution operator?
因为它没有(正确地)在命名空间中声明,并且如果函数已经声明,则只能在其命名空间之外定义(使用范围解析).
Because it hasn't been (properly) declared in the namespace, and a function can only be defined outside its namespace (with scope resolution) if it has been declared.
为什么flag会消除错误?
Why does the flag eliminate the error?
因为标志导致友元声明充当命名空间中的声明.这是为了与 C++ 的古代方言(显然还有一些现代编译器)兼容,其中这是标准行为.
Because the flag causes the friend declaration to act as a declaration in the namespace. This is for compatibility with ancient dialects of C++ (and, apparently, some modern compilers) in which this was the standard behaviour.
相关文章