标准陈述
时,它究竟意味着什么$ 7.3.1.1 / 2 - “使用静态 声明时不推荐使用关键字 命名空间范围内的变量(参见 附件D); unnamed-namespace 提供了一个更好的选择。“
我提到了this,但它没有涵盖我正在寻找的内容。
是否有一个明显证明优势的例子。
注意:我知道未命名的命名空间如何在翻译单元中显示外部变量,并将其隐藏在其他翻译单元中。但这篇文章的重点是'静态命名空间范围'名称(例如全局静态变量)
答案 0 :(得分:11)
技术上已弃用表示未来的标准可能会删除该功能。
在实践中,由于需要支持旧代码,所以不会发生。
所以在实践中它意味着“强烈气馁”。
一个未命名的命名空间通常更优越,因为您在该命名空间中拥有的内容可以具有外部链接。
在C ++ 98中,外部链接对于可以作为模板参数的内容是必要的,例如,如果要在char const*
上进行模板化,则它必须是指向具有外部链接的char
的指针。
#include <iostream>
// Compile with "-D LINKAGE=static" to see problem with "static"
#ifndef LINKAGE
# define LINKAGE extern
#endif
template< char const* s >
void foo()
{
std::cout << s << std::endl;
}
namespace {
LINKAGE char const message[] = "Hello, world!";
} // namespace anon
int main()
{
foo<message>();
}
那就是说,static
对于函数也没有被弃用,这有点不一致。
答案 1 :(得分:10)
此:
static int func_for_this_file_only() { ... }
“和”一样好“:
namespace { int func_for_this_file_only() { ... } }
但static
不能用于此:
namespace { class class_for_this_file_only { ... } }
因此,C ++中的匿名命名空间更加通用,并且优于static
。
(我确信有人会争论这个结论,但作为一名C黑客,我认为匿名命名空间解决方案更好。)
答案 2 :(得分:6)
有趣的是,ISO / IEC 14882:2011(C ++ 11)删除了这种语言(事实上,它删除了整个段落§7.3.1.1/ 2)。它还删除了附件D中提到的static
。
因此,使用存储类说明符static
来提供名称内部链接仍然有效(§3.5/ 3)并且不再被弃用。
答案 3 :(得分:2)
目标是定义仅存在于您自己的翻译单元中的符号。这可以是“全球翻译单位”,可以是变量或函数。
这通常在类定义文件中用作私有静态类成员的替代,因为必须在标头中声明静态成员,但不必是自由函数(除非它必须是朋友顺便说一句,它实际上并不是真正需要的。
静态的使用将是:
static size_t BUFSIZE = 2048; // assume not const for this example
static int myCallback( void * ptr );
使用匿名命名空间是
namespace {
size_t BUFSIZE = 2048;
int myCallback( void * ptr );
}
标准是说第二种结构是首选。我们发现有时除了匿名命名空间之外还使用静态来实际减少二进制大小是有利的。