[英]implementing or defining class or function declared inside an unnamed/anonymous namespace
Is it legal to define the implementation of a function or class members outside the unnamed (anonymous) namespace they've been defined inside.在内部定义的未命名(匿名)命名空间之外定义 function 或 class 成员的实现是否合法。 My compiler accepts it but I want to be sure it's legal eg
我的编译器接受它,但我想确保它是合法的,例如
////////////////
// foo.cpp
namespace {
struct X
{
void foo(int x);
};
}
// Is this legal?
void X::foo(int x)
{
}
The reason is I would like to avoid the unnecessary indentation imposed by our uncrustify formatting原因是我想避免我们的 unrustify 格式带来的不必要的缩进
It is really no different than the following, which is totally legit:它实际上与以下内容没有什么不同,这是完全合法的:
namespace ns {
struct s {
void f();
};
}
using namespace ns;
void s::f() { }
The names from the named namespace are brought into the global namespace and thus definitions can be provided for them there.命名命名空间中的名称被带入全局命名空间,因此可以在那里为它们提供定义。 The only difference with the unnamed namespace is that it has no name (really, it has some unique, unutterable name) and the
using namespace
is implicit.与未命名命名空间的唯一区别是它没有名称(实际上,它有一些唯一的、无法说出的名称)并且
using namespace
是隐式的。
It's legal in your scenario, but in one scenario, it will cause compiler ambiguous error.这在您的场景中是合法的,但在一种情况下,它会导致编译器模棱两可的错误。
In case have another class in Xh:如果 Xh 中有另一个 class:
// X.h
struct X
{
void foo(int x) { }
};
And in foo.cpp, need to use the X defined in Xh而在foo.cpp中,需要用到Xh中定义的X
////////////////
// foo.cpp
#include "X.h"
namespace {
struct X
{
void foo(int x);
};
// use the X declared in anonymous namespace
void test()
{
X x;
x.foo(3);
}
}
// reference to 'X' is ambiguous
void X::foo(int x)
{
}
void otherFunction()
{
// Use struct X in X.h
::X x;
x.foo(3);
}
if leave the implementation code out of the anonymous namespace, compiler complains ambiguous.如果将实现代码留在匿名命名空间之外,编译器会抱怨模棱两可。 If move the implementation code inside anonymous namespace, it works fine.
如果将实现代码移动到匿名命名空间内,它可以正常工作。
#include <iostream>
using namespace std;
namespace
{
struct X
{
X(int);
int x_;
};
}
X::X(int x) : x_(x) {}
int main()
{
X x(5);
cout << x.x_ << "\n";
return 0;
}
Compiles (and runs) under gcc 4.6.0在 gcc 4.6.0 下编译(并运行)
Yes.是的。 It's perfectly legal.
这是完全合法的。 The difference an unnamed namespace makes is that, the content of the namespace is available only within the file it's declared.
未命名命名空间的不同之处在于,命名空间的内容仅在其声明的文件中可用。 If it's in
.h
file then, it will be added to all the subsequent .cpp
file and every .cpp
file will have a unique copy of the contents of the namespace
.如果它在
.h
文件中,那么它将被添加到所有后续的.cpp
文件中,并且每个.cpp
文件都将具有namespace
内容的唯一副本。
In fact it's a better way to declare a global static
variable.实际上,这是声明全局
static
变量的更好方法。 Now see, what kind of difference it will make:现在看看,它会产生什么样的不同:
namespace {
struct X
{
void foo(int x);
};
int i; // declare this global variable
}
If you put this code inside a header file then, wherever that header file is #include
ed, all those .cpp
file will have a different copy of int i;
如果将此代码放在 header 文件中,那么无论 header 文件是
#include
ed,所有这些.cpp
文件都将具有不同的int i;
inside them.在他们里面。 Changing the value of
i
in one .cpp
file doesn't affect the other .cpp
file.在一个
.cpp
文件中更改i
的值不会影响另一个.cpp
文件。
Moreover, it will not give linker error for multiple definitions, since it's in unnamed namespace
.此外,它不会对多个定义给出 linker 错误,因为它位于 unnamed
namespace
中。
Edit : To evaluate it more, define the namespace as following:编辑:要对其进行更多评估,请按如下方式定义命名空间:
// x.h
namespace
{
struct X
{
void foo(int x)
{
static int c; // static inside the function
cout<<"a = "<<(c++)<<endl;
}
};
}
Now #include
this header file in 2 different .cpp
files.现在
#include
这个 header 文件在 2 个不同的.cpp
文件中。 In both of them try to call foo()
with object of X
.在他们两个中尝试使用
X
的 object 调用foo()
。 It will print:它将打印:
a = 0
a = 0
Which means that X::foo()
in both the .cpp
files are different .这意味着两个
.cpp
文件中的X::foo()
是不同的。 If you give the namespace
a name and repeat the same thing, it will output如果你给
namespace
一个名字并重复同样的事情,它会 output
a = 0
a = 1
Thus unnamed namespace
creates a different copy for each translation unit.因此,未命名的命名
namespace
会为每个翻译单元创建不同的副本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.