Yve*_*ner 24 c++ namespaces c++11 inline-namespaces
请考虑以下代码:
#include <iostream>
namespace Foo{
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
inline namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
Foo::ool(); // <- error
}
Run Code Online (Sandbox Code Playgroud)
Clang和G ++都正确地标记Foo::ool
为含糊不清.我可以Foo::Bar::ool
毫无问题地打电话但有没有办法在不改变声明的情况下调用版本A?
我发现处于类似位置的人试图了解会发生什么,但我没有看到这种情况的解决方案.
我处于这种情况,因为我有一个项目,其中包含一个声明,std::__1::pair
并std::pair
在不同的地方,std::__1
作为内联命名空间.我需要代码std::pair
明确指向.有解决方案吗?
Sva*_*zen 12
我不认为这是可能的; 来自cppreference:
检查封闭命名空间的限定名称查找将包括内联命名空间中的名称,即使封闭命名空间中存在相同的名称也是如此.
但是,您似乎并没有真正处理您描述的情况,因为您说这两个定义是从不同的文件中提取的.因此,您可以"标记"更多的外部定义,以便能够在需要时调用它:
#include <iostream>
// Equivalent of first include
namespace Foo{
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
}
const auto& foo_ool = Foo::ool;
// Equivalent of second include
namespace Foo{
inline namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
foo_ool(); // Works
}
Run Code Online (Sandbox Code Playgroud)
如果你想要书签的东西是一个类型,一个简单的using
指令就足够了.您的等效代码如下所示:
#include <my_first_include>
// bookmark code
#include <my_second_include>
// rest of the code
Run Code Online (Sandbox Code Playgroud)
一旦看到内联命名空间,就无法明确地引用封闭命名空间中定义的符号.
特别是对于你的情况,合格的查找main
被正确地标记为含糊不清(正如你自己所说).请参阅cppreference的最后一点:
检查封闭命名空间的限定名称查找将包括内联命名空间中的名称,即使封闭命名空间中存在相同的名称也是如此.
然而,还有其他人在评论中指出,当您尝试使用时,您可能在工具链调用中遇到配置问题std::pair
.
要解决您的问题,您需要确保调用编译器来编译C++ 11代码,该代码将带有标志:
-std=c++11
或-std=c++0x
取决于您的Clang/GCC版本
进一步提供上下文:
内联命名空间是一个C++ 11特性,主要用于允许在库中进行符号版本控制.然后,C++标准库实现可以在嵌套命名空间中定义不同版本的符号(使用非标准名称),并且在编译时根据请求的库版本,工具链将这些嵌套命名空间中的一个定义为内联.看来你正在使用库的c ++ 11版本(因为它定义了一些符号,特别pair
是在内联命名空间中_1
),因此在内联命名空间中实际符合你想要的符号.