inline namespace
C++11新增的内联名字空间要解决的问题是,在父名字空间定义或特化子名字空间的模板。
我们看以下程序,有了inline修饰符,Other里就能特化Basic里的模板类,外层的Jim里也能特化Toolkit类了。
#include <iostream>
using namespace std;
namespace Jim {
inline namespace Basic {
struct Knife{ Knife() { cout << "Knife in Basic." << endl; } };
class CorkScrew{};
}
inline namespace Toolkit {
template<typename T> class SwissArmyKnife{};
}
// ...
namespace Other {
Knife b; // basic
struct Knife { Knife() { cout << "Knife in Other" << endl; } };
Knife c; // other
Basic::Knife k; // basic
}
}
namespace Jim {
template<> class SwissArmyKnife<Knife>{};
}
using namespace Jim;
int main() {
SwissArmyKnife<Knife> sknife;
}
/*
Knife in Basic.
Knife in Other
Knife in Basic.
*/
ADL
C++的一个语言特性是ADL,全称是Argument-Dependent name Lookup,参数关联名称查找,允许编译器在名字空间内找不到函数名字的时候,在参数的名字空间内进行查找。
比如下面的例子,我们在main函数里调用ADLFunc时没有加namespace,但编译不会报错,因为编译器在找不到ADLFunc这个符号时,会failover从参数a那里继续找。这个特性在C++98里也有的。
namespace ns_adl {
struct A{};
void ADLFunc(A a){}
}
int main() {
ns_adl::A a;
ADLFunc(a);
}
ADL在一定情况下可以解决inline namespace要解决的问题,带来了使用上的便利性,不过也在一定程度上破坏了namespace的封装性,有的人认为有负面影响。笔者也建议不要依赖这个特性,该加的namespace还是要加的。
网友评论