[C++11阅读][2-5-1]内联名字空间

2020-06-14  本文已影响0人  凌霄阁2010

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还是要加的。

上一篇 下一篇

猜你喜欢

热点阅读