目录
命名空间的作用
开发大型软件通常需要许多开发人员并使用很多第三方库,为了防止函数和类型命名冲突,因此引入命名空间。
在使用函数和类型时,可以指定它们的命名空间,这样就不会产生冲突。
来看一个例子:
#include <iostream>
namespace S1 {
void foo() {
std::cout << "S1 foo() called!" << std::endl;
}
}
namespace S2 {
void foo() {
std::cout << "S2 foo() called!" << std::endl;
}
}
using namespace S1;
int main() {
foo();
S2::foo();
return 0;
}
运行结果:
linrongjian@hhb-ssd:/data/modern_cpp$ g++ -std=c++11 namespace_example.cpp -o namespace_example
linrongjian@hhb-ssd:/data/modern_cpp$ ./namespace_example
S1 foo() called!
S2 foo() called!
这里使用 using
关键字打开了 S1
命名空间,所以 S1
的 foo
函数可以直接使用(而不用在前面加上 S1::
),而调用 S2
的函数需要用这种方式:S2::foo()
。
当然这里也可以不打开命名空间,这样使用任何函数都需要在前面加上命名空间和作用域运算符 ::
。
内联命名空间 inline namespace(C++11)
C++11 引入了内联命名空间,可以把一个子命名空间内的函数和类型导出到父命名空间中。
这样,如果不指定子命名空间,则默认使用该内联命名空间内的函数和类型。
因此,为了防止二义性,在一个父命名空间内只能有一个子命名空间作为内联命名空间。
来看一个例子:
#include <iostream>
namespace Parent {
namespace Child1 {
void foo() {
std::cout << "Child1::foo()" << std::endl;
}
}
inline namespace Child2 {
void foo() {
std::cout << "Child2::foo()" << std::endl;
}
}
}
int main() {
Parent::Child1::foo();
Parent::foo();
}
这里子命名空间 Child2
作为父命名空间 Parent
的内联命名空间,如果不指定子命名空间,调用函数时会默认调用 Child2
内的函数实现:
linrongjian@hhb-ssd:/data/modern_cpp$ g++ -std=c++11 inline_namespace.cpp -o inline_namespace
linrongjian@hhb-ssd:/data/modern_cpp$ ./inline_namespace
Child1::foo()
Child2::foo()
内联命名空间有什么用?
内联命名空间可以用来升级库代码,可以使用命名空间来管理不同版本的库代码,然后将最新版本的接口以内联的方式导出到父命名空间中。
例子:
#include <iostream>
namespace Parent {
namespace V1 {
void foo() {
std::cout << "foo() v1.0" << std::endl;
}
}
// use v2 as newest version
inline namespace V2 {
void foo() {
std::cout << "foo() v2.0" << std::endl;
}
}
}
int main() {
Parent::foo();
}
运行结果:
linrongjian@hhb-ssd:/data/modern_cpp$ g++ -std=c++11 inline_namespace_example.cpp -o inline_namespace_example
linrongjian@hhb-ssd:/data/modern_cpp$ ./inline_namespace_example
foo() v2.0
嵌套命名空间的简洁用法(C++17)
C++17
引入了一种简洁的形式表示嵌套命名空间。
例如:
namespace A {
namespace B {
namespace C {
void foo();
}
}
}
等价于:
namespace A::B::C {
void foo();
}
嵌套定义内联命名空间(C++20)
类似于 C++17
的定义嵌套命名空间的简洁用法,C++20
可以这样在嵌套命名空间中定义内联命名空间:
namespace A::B::inline C {
void foo();
}
与之等价的写法是:
namespace A::B {
inline namespace C {
void foo();
}
}
也可以不指定最下层的命名空间为内联命名空间:
namespace A::inline B::C {
void foo();
}
与之等价的写法是:
namespace A {
inline namespace B {
namespace C {
void foo();
}
}
}
总结:inline
可以出现在除第一个 namespace
(也就是最外层的 namespace
)之外的任意 namespace
之前。
参考资料
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/287830.html