C++ 纯标头库避免“使用命名空间”污染

wor*_*nga 2 c++ namespaces c++11

我有一个带有多个命名空间的纯头文件 C++ 库。

例如一个头文件可能包含

//header1.h
namespace library{
namespace componentA{
   template<typename T>
   class Someclass{};
}
}
Run Code Online (Sandbox Code Playgroud)

还有另外一个

//header2.h
namespace library{
namespace componentB{
   template<typename T>
   class SomeOtherClass{
       void Foo(const componentA::Someclass<T>& reference);
       void Bar(const componentA::Someclass<T>& reference);
   };
}
}
Run Code Online (Sandbox Code Playgroud)

现在,虽然这有效,但拥有一个仅包含头文件的库,一次又一次地编写命名空间变得很乏味,特别是当您涉及多个类和嵌套命名空间时。

所以我这样做了:

//new header2.h
namespace library{
namespace componentB{

   using namespace componentA;

   template<typename T>
   class SomeOtherClass{
       void Foo(const Someclass<T>& reference);
       void Bar(const Someclass<T>& reference);
       void FooBar(const Someclass<T>& reference);
       void FooWithBar(const Someclass<T>& reference);
   };
}
}
Run Code Online (Sandbox Code Playgroud)

虽然这肯定更方便键入,但它存在一个问题,即现在库的客户端也可以Someclass<T>通过使用componentB这样的命名空间来使用,这会导致接口不明确,并最终导致代码不一致。例如,客户端现在可以使用, componentB::Someclass<T>即使它最初是在componentA

有没有办法让速记只能“私下”使用?

Yak*_*ont 6

namespace library {
  namespace componentAImpl{
    using ::library::componentB;
    // ...
    inline namespace exports{
      struct foo{};
    }
  }
  namespace componentA{
    using namespace library::componentAImpl::exports;
  }
}
Run Code Online (Sandbox Code Playgroud)

用户可以访问componentAImpl,但不应该访问。

同时,一组干净的符号暴露在library::componentA.