我理解使用未命名的命名空间来使函数和变量具有内部链接.头文件中不使用未命名的命名空间; 只有源文件.源文件中声明的类型不能在外部使用.那么在未命名的命名空间中放置类型有什么用呢?
请参阅这些链接,其中提到的类型可以放在未命名的命名空间中:
使用未命名的命名空间和全局声明有什么区别?
使用这两个是否有任何特定的背景?
我们可以在外部源文件中访问未命名的命名空间组件吗?
SO最近的一个帖子触发了这一点。
未命名的命名空间被认为等同于
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
Run Code Online (Sandbox Code Playgroud)
我记不起它不等于的确切原因
namespace unique { namespace-body }
using namespace unique;
Run Code Online (Sandbox Code Playgroud)
也尝试过搜索(包括谷歌)但没有成功。请分享您在这方面掌握的任何信息。
c++ namespaces using-declaration language-lawyer unnamed-namespace
在Google C++样式指南中,命名空间部分指出" 在头文件中使用未命名的命名空间很容易导致违反C++ One Definition Rule(ODR). "
我理解为什么不在实现文件中使用未命名的命名空间可能会导致ODR违规,但不能在标头中使用它们.这怎么会导致违规?
我一直在公司里看到这样的代码:
namespace {
const MAX_LIMIT = 50;
const std::string TOKEN = "Token";
}
Run Code Online (Sandbox Code Playgroud)
我很困惑,为什么你需要一个匿名命名空间.一方面,您需要MAX_LIMITAND 的本地翻译单元TOKEN.但是,由于这个原因,没有匿名命名空间就已经实现了const.static const而且简单const都实现了本地翻译单元.
另一方面,如果文件中的某个地方有一个名为相同的变量,则没有命名冲突.
int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}
Run Code Online (Sandbox Code Playgroud)
这将证明匿名命名空间的合理性.但是,您在函数中需要一个变量名称的频率实际上是在函数const外部声明的变量吗?我的回答永远不会.所以在实践中,对我来说不需要未命名的命名空间.任何提示?
C++20 引入了模块。任何未在模块中导出的符号都具有模块内部链接。虽然未命名命名空间提供了一种机制,可以使未命名命名空间内的定义具有文件内部链接。这是否意味着当模块在 C++ 社区中成为普遍做法时,未命名的命名空间将变得毫无用处?
我一直在使用一个肮脏的技巧,我使用未命名的名称空间来为每个文件指定不同的行为(用于单元测试)。感觉它不应该被明确定义,但它适用于过去六年发布的每个主要编译器。
我首先在匿名名称空间中前向声明一堆类:
namespace {
class context_check;
class context_block;
class register_test;
} // namespace
Run Code Online (Sandbox Code Playgroud)
然后我声明一个类并创建这些类friend:
struct test_case
{
// ...
};
class context {
// ...
private:
// TODO: this feels like ODR-violation...
friend class context_check;
friend class context_block;
friend class register_test;
private:
void add_test(test_case&& test)
{
// ...
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
在每个 cpp 文件中,我都有以下声明(为了简单起见,我将它们复制并粘贴到此处,但实际上我在标头中声明了未命名命名空间的内容):
// A.cpp
namespace {
extern context file_context;
class register_test {
public:
register_test(const char* test_name, test_case&& test)
{
file_context.add_test(std::move(test));
}
};
} // namespace …Run Code Online (Sandbox Code Playgroud) 我有这个:
#include <iostream>
using namespace std;
// Variable created inside namespace
namespace first
{
int val = 500;
}
namespace
{
int val = 400;
}
// Global variable
//int val = 100;
int main()
{
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
cout << ::val << '\n';
cout << val << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况::val …
根据 C++ 标准的第 3.5/4 条:
未命名命名空间或在未命名命名空间内直接或间接声明的命名空间具有内部链接。
同时在第 7.3.1.1 段中,我们有注释 96):
尽管未命名命名空间中的实体可能具有外部链接,但它们有效地由其翻译单元唯一的名称限定,因此无法从任何其他翻译单元看到。
如果标准保证无法从另一个翻译单元访问未命名命名空间内定义的名称,如何显式地为未命名命名空间内的名称建立外部链接,以及如何检查链接实际上是外部的?
在哪些情况下对未命名命名空间内的名称进行显式外部链接有用?
我有以下代码,但我不知道如何在此设置中访问匿名命名空间内的 x。请告诉我怎么做?
#include <iostream>
int x = 10;
namespace
{
int x = 20;
}
int main(int x, char* y[])
{
{
int x = 30; // most recently defined
std::cout << x << std::endl; // 30, local
std::cout << ::x << std::endl; // 10, global
// how can I access the x inside the anonymous namespace?
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 这个问题已经在命名空间内的未命名命名空间链接中讨论过 ,但对于如何访问嵌套在命名空间下的未命名命名空间的变量(如果两个变量相同)没有提供完美的答案
考虑这段代码
namespace apple {
namespace {
int a=10;
int b=10;
}
int a=20;
}
int main()
{
cout<<apple::b; //prints 10
cout<<apple::a; // prints 20
}
Run Code Online (Sandbox Code Playgroud)
未命名的命名空间"variable a"始终是隐藏的。如何访问"variable a"未命名的命名空间?
在命名空间内声明未命名的命名空间是否合法?
请考虑以下代码:
#include<iostream>
namespace
{
int a = 5;
}
namespace
{
int a = 5;
}
int main()
{
int i=5;
{
std::cout << i;
}
}
Run Code Online (Sandbox Code Playgroud)
此代码无效.这是因为a发生了重新定义.但我希望这是有效的.实际上,秒.3.3.6/1说:
[...] original-namespace-name表示的潜在范围是由同一声明性区域中的每个名称空间定义与原始名称空间名称建立的声明性区域的串联 .[...]
但未命名的命名空间定义不是原始命名空间定义和秒.7.3.1/1说:
namespace-name:
original-namespace-name
namespace-alias
original-namespace-name:
identifier
Run Code Online (Sandbox Code Playgroud)
和
original-namespace-definition:
inline_opt namespace identifier { namespace-body }
Run Code Online (Sandbox Code Playgroud)
而且,秒.7.3.1.1说:
未命名的命名空间定义的行为就像被替换为
Run Code Online (Sandbox Code Playgroud)inlineopt namespace unique { /* empty body */ } using namespace unique ; namespace unique { namespace-body }当且仅当它出现在unnamed-namespace-definition中时,inline才会出现,翻译单元中所有出现的unique都会被相同的标识符替换,并且此标识符与整个程序中的所有其他标识符不同.
这意味着两个未命名的命名空间具有不同的唯一.
你能解释我引用的代码中的行为吗?
c++ ×12
namespaces ×6
anonymous ×2
c++14 ×2
c++-modules ×1
declaration ×1
global ×1
globals ×1
static ×1