当内联命名空间存在时,如何显式引用封闭命名空间?
How can I explicitly refer to an enclosing namespace when an inline namespace exists?
请考虑以下代码:
#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
}
Clang和g++都正确地将Foo::ool
标记为二义性。我可以调用Foo::Bar::ool
没有问题,但是有没有一种方法可以调用版本a而不改变它的声明?
我发现有类似情况的人试图理解发生了什么,但我没有看到一个解决方案。
我在这种情况下,因为我有一个项目,其中包括std::__1::pair
和std::pair
的声明,在不同的地方,std::__1
是一个内联命名空间。我需要代码明确地指向std::pair
。有解决办法吗?
我认为这是不可能的;从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
}
如果你想收藏的东西是一个类型,一个简单的using
指令应该足够了。您的等效代码看起来像:
#include <my_first_include>
// bookmark code
#include <my_second_include>
// rest of the code
一旦看到内联命名空间,就不能明确地引用在封闭命名空间中定义的符号。
特别是在您的情况下,main
中的限定查找被正确地标记为模棱两可(正如您自己所说)。参见cppreference的最后一点:
检查封闭名称空间的限定名称查找将包括来自内联名称空间的名称,即使在封闭名称空间中存在相同的名称。
然而,其他人在评论中指出,当您尝试使用std::pair
时,您可能面临工具链调用中的配置问题。
要解决这个问题,您需要确保调用编译器来编译c++ 11代码,这将带有标志:
-std=c++11
或-std=c++0x
取决于您的Clang/GCC版本
给出进一步的上下文:
内联命名空间是c++ 11的一个特性,主要是为了允许库中的符号版本控制而引入的。然后,c++标准库实现可以在嵌套命名空间中定义不同版本的符号(使用非标准名称),并且根据编译时请求的库版本,工具链将这些嵌套命名空间中的一个定义为内联的。似乎您正在使用c++11版本的库(因为它定义了一些符号,特别是pair
,在内联命名空间_1
中),所以在内联命名空间中实际上有您想要的符号。
当内联命名空间确实有与ool
同名的方法时,我不认为您可以含糊地引用ool
。
But You can try this;
#include <iostream>
namespace Foo{
inline namespace A {
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
}
namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
Foo::ool(); // no error
}
- 将
namespace Foo
中的方法包装到namespace A
中,然后将inline
中的namespace A
中。 - 从
Bar
中删除内联。
现在如果你调用Foo::ool();
,它将调用inline A::ool()
Bar::ool
可以被Foo::Bar::ool
调用
- 不同C++文件中未命名命名空间中的名称可以引用同一个命名事物吗?
- 命名空间中未引用的函数
- 有没有办法在不使用命名空间 std 或前缀 std:: 的情况下引用 cout?
- 使用多个命名空间对 vtable 的未定义引用
- 在 c++ 中在运行时声明对命名空间的引用
- 如何在命名空间中引用用户定义的文本运算符
- 即使在使用命名空间指令后也没有明确的引用错误
- 使用 "::member" 引用全局命名空间有什么用吗?
- 对"vtable for "命名空间继承的未定义引用 对"类型信息"的未定义引用
- 命名空间中的内联函数提供对C++的未定义引用
- cpp:关于未定义引用"(匿名命名空间)::CPassant::NbCPassant"的说明
- 3 文件项目中未定义引用中的 C++ 命名空间
- 引用封闭命名空间
- 您可以使用没有 :: 的命名空间引用其他类中的函数吗?
- 从另一个类引用命名空间
- 如何为匿名命名空间中未引用的本地函数生成警告
- 对 C++ 中命名空间的未定义引用
- 引用命名空间中的结构类型
- (C++)不能引用命名空间内的枚举类
- 命名空间和未定义的引用