'using namespace'实现细节的便捷方法(仅标头库)?

Convenient way of 'using namespace' in implementation details (header only library)?

本文关键字:namespace using 实现 细节 方法      更新时间:2023-10-16

所以我在这个库(仅标题(上工作,该库具有多个模块并使用内联命名空间进行版本控制。因此,完全限定的名称有时会变得更长一些。我想使用"使用命名空间 x"作为(内联(详细命名空间内的实现细节,但这会污染外部命名空间。

请参阅Godbolt上的示例代码:https://godbolt.org/z/pdSXrs

我找到了两种解决方法(请参阅 godbolt 链接(,它们可以做我想做的,但似乎过于复杂。有没有更简单的方法可以做到这一点?我应该只输入所有完全限定的名称(并保持错误消息更清晰(吗?我很想知道"更复杂的"命名空间构造的最佳实践是什么。

编辑:根据建议添加代码

// think of these as in header files
namespace mylib{
namespace module0{
inline namespace mystuff{
// this constant conceptually belongs to module 0 but might be used as an
// implementation detail in other modules
int myconst = 42;
}
}
}
namespace mylib{
namespace module1{
// I would like to use this, but pollutes mylib::module1 namespace
inline namespace detail1{
using namespace mylib::module0::mystuff;
struct foo1{
int operator()(){
return myconst;
}
};          
}
}
}
namespace mylib{
namespace module2{
inline namespace detail1{
// this works but seems overly complicated
namespace more_detail{
using namespace mylib::module0::mystuff;
struct foo2{
int operator()(){return myconst;}
};
}
// might be very cumbersome to use if lots of classes
using more_detail::foo2;
}
}
}
namespace mylib{
namespace module3{
inline namespace detail1{
// is this a good way to namespace a library...?
namespace more_detail{
using namespace mylib::module0::mystuff;
// not enough namespaces yet?!
namespace devil_of_details{
struct foo3{
int operator()(){return myconst;}
};
}
}
// useable for lots of classes/types in that namespace... but really?!
using namespace more_detail::devil_of_details;
}
}
}
// think of this as myprogram.cpp including the headers
#include <iostream>
int main(){
// polluted namespace. I can probably live with it, but it's not ideal
// constant should only be visible in module0
int x1 = mylib::module1::myconst;
std::cout << x1 << std::endl;
// ok
int x0 = mylib::module0::myconst;
// this is what I ideally want, i.e. not polluting module2 namespace
int x2_error = mylib::module2::myconst;
// this is what I ideally want, i.e. not polluting module3 namespace
int x3_error = mylib::module3::myconst;
// normal usage in cpp file
using namespace mylib::module2;
int x2 = foo2{}();
std::cout << x2 << std::endl;
// ok
using namespace mylib::module0;
std::cout << myconst << std::endl;
}

我会建议命名空间别名。

命名空间 mylib{ 命名空间模块 1{ 命名空间详细信息0 = 模块0::mystuff; } }

虽然这使得其他命名空间可见,但它实际上并没有像using那样导入符号,也就是说mylib::module1没有myconst成员。

另外,请注意,只要您当前定义的命名空间是mylib的一部分,就不需要将mylib作为名称的一部分。即使您关闭mylib然后重新打开它。

那是:

命名空间 mylib { 命名空间部分 1 {/* ... */} } 命名空间 mylib { 命名空间 part2 { namespace p1 = part1; } }

p1将引用mylib::part1,只要您不指定它是完全限定的名称 (::part1(。