Answers:
未命名的名称空间是使标识符转换单元位于本地的实用程序。它们的行为就像您为名称空间的每个翻译单元选择唯一的名称一样:
namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }
使用空主体的额外步骤很重要,因此您已经可以在名称空间主体中引用该名称空间::name
中定义的标识符,因为using指令已经发生。
这意味着您可以拥有(例如)help
可以存在于多个翻译单元中的自由函数,并且它们在链接时不会发生冲突。其效果几乎与使用static
C语言中使用的关键字相同,您可以将其放入标识符的声明中。未命名的命名空间是一种更好的选择,甚至可以将类型转换单元设置为本地。
namespace { int a1; }
static int a2;
两者a
都是本地翻译单位,在链接时不会发生冲突。但是不同之处在于a1
,匿名名称空间中的会获得唯一的名称。
在comeau-computing中阅读出色的文章为什么使用未命名的名称空间而不是静态名称空间?(Archive.org镜像)。
在匿名名称空间中包含某些内容意味着该内容在此翻译单元(.cpp文件及其所有包含)中是本地的,这意味着如果在其他位置定义了另一个具有相同名称的符号,则不会违反单一定义规则(ODR)。
这与C具有静态全局变量或静态函数的方式相同,但是它也可以用于类定义(并且应static
在C ++中使用,而不是在C ++中使用)。
同一文件中的所有匿名名称空间都被视为同一名称空间,并且不同文件中的所有匿名名称空间是不同的。匿名名称空间等效于:
namespace __unique_compiler_generated_identifer0x42 {
...
}
using namespace __unique_compiler_generated_identifer0x42;
未命名的命名空间将类,变量,函数和对象的访问权限限制在其定义文件中。未命名的名称空间功能类似于static
C / C ++中的关键字。
static
关键字限制了对全局变量和函数对其定义文件的访问。
未命名的名称空间和static
关键字之间存在差异,因为未命名的名称空间比静态名称空间具有优势。static
关键字可以与变量,函数和对象一起使用,但不能与用户定义的类一起使用。
例如:
static int x; // Correct
但,
static class xyz {/*Body of class*/} //Wrong
static structure {/*Body of structure*/} //Wrong
但是,使用未命名的名称空间也可以实现。例如,
namespace {
class xyz {/*Body of class*/}
static structure {/*Body of structure*/}
} //Correct
除了该问题的其他答案之外,使用匿名名称空间还可以提高性能。由于名称空间中的符号不需要任何外部链接,因此编译器可以自由地对名称空间中的代码执行积极的优化。例如,可以内联一个在循环中多次调用的函数,而不会影响代码大小。
例如,在我的系统上,如果使用匿名名称空间,则以下代码将花费大约70%的运行时间(x86-64 gcc-4.6.3和-O2;请注意,add_val中的额外代码使编译器不希望包含它两次)。
#include <iostream>
namespace {
double a;
void b(double x)
{
a -= x;
}
void add_val(double x)
{
a += x;
if(x==0.01) b(0);
if(x==0.02) b(0.6);
if(x==0.03) b(-0.1);
if(x==0.04) b(0.4);
}
}
int main()
{
a = 0;
for(int i=0; i<1000000000; ++i)
{
add_val(i*1e-10);
}
std::cout << a << '\n';
return 0;
}
-O3
自身进行了比较,那么您说3到4秒是“同一时间”。这些都不有意义。我怀疑真正的解释会,但这是什么?
该示例表明,您加入的项目中的人员不了解匿名名称空间:)
namespace {
const int SIZE_OF_ARRAY_X;
const int SIZE_OF_ARRAY_Y;
这些对象不必位于匿名名称空间中,因为const
对象已经具有静态链接,因此不可能与另一个翻译单元中相同名称的标识符冲突。
bool getState(userType*,otherUserType*);
}
这实际上是一种悲观:getState()
具有外部联系。通常最好选择静态链接,因为它不会污染符号表。最好写
static bool getState(/*...*/);
这里。我陷入了同样的陷阱(标准中的措辞表明,不赞成使用文件静态方法,而赞成使用匿名名称空间),但是在像KDE这样的大型C ++项目中工作时,会遇到很多人以正确的方式前进再来一遍:)
const
ness 并没有什么害处。以后再根据需要。我怀疑这意味着OP团队“什么都不懂”!另外,如前所述,在具有外部链接的匿名命名空间中,有关函数的说法是错误的。据我了解,它们解决了以前需要外部链接的模板参数问题,因此可以允许未命名的名称空间(能够包含模板args)具有内部链接。
匿名名称空间使封闭的变量,函数,类等仅在该文件内部可用。在您的示例中,这是避免全局变量的一种方法。没有运行时或编译时性能差异。
除了“我希望此变量,函数,类等是公共的还是私有的”之外,没有什么优点或缺点。
static
。能否请您比较一下__attribute__ ((visibility ("hidden")))
?