是否有任何方法可以阻止命名空间在c++中添加更多的类?
Is there any way I can prevent a namespace from adding further classes in C++?
我想创建一个名称空间,并防止它添加任何更多的类或其他东西。我有什么办法可以做到吗?
.
@LightnessRacesinOrbit的回答是以下引用自标准
7.3名称空间(basic.namespace)
1名称空间是一个可选命名的声明性区域。可以使用命名空间的名称进行访问在该命名空间中声明的实体;的成员名称空间。与其他声明性区域不同,命名空间可以拆分为一个或多个翻译的几个部分单位。
因为翻译单元的数目是一个开放集合,所以命名空间的隶属关系是开放的。
然而,正如@Galik所建议的,您可以通过编写仅包含静态成员函数的结构或类来不完美地模拟封闭命名空间
struct closed_namespace {
static void fun() { /* bla */ }
};
名称空间到结构体的转换可能不是100%插入式的。例如,普通的名称查找可能会起到相同的作用,但您总是需要限定函数,因此ADL将被排除在外。
但调用代码几乎相同(即使用::
访问器)
closed_namespace::fun();
,你也可以使用类型定义来缩短长名称,c++ 11 using
语法类似于从左到右命名空间别名
using cn = closed_namespace;
另一方面,using指令和声明不能结转。
没有语言支持。这就是为什么您可以通过添加不应该添加的东西(如type_traits
专门化)来混淆std
名称空间。
我觉得不太需要这么做,因为如果我真的想的话,我可以通过简单地编辑源文件来做到这一点,但这并不是一个真正有意义的破坏程序的方法。
考虑到namespace
s可以被多个tu扩展,那么您如何选择应该"终止"哪个名称空间呢?你能这样做吗,在某个点上它变得有问题,你goto
前一段
我同意这是一个简单的布尔答案,真的不需要进一步的阐述,除了我们所有人都在说"我也是"或"不,你需要更啰嗦"。有时简洁是好的(并回答问题)。然而…
如果你想一下,这将是一个巨大的变化,整个工具链来执行这一点。元数据根本没有(如果有的话)保存在正确的位置,因此鼓励/需要(?为IP保护,但开源的人不会关心!)头文件(声明)和源体(实现)之间的分离会使编译器供应商更加混乱。我怀疑它根本不会获得任何牵引力,因为除非(即使没有)你让每个供应商/项目注册一个命名空间或使用一个UUID,否则冲突的可能性就太大了。
// <header1>
// Yick! (IMO)
namespace frozen std_A1DD3D0F_DC56_41D4_9B87_F820B420A94D
{
class foo { ... };
}
// <header2>
// Now what?
namespace frozen std_A1DD3D0F_DC56_41D4_9B87_F820B420A94D
{
class bar{ ... };
}
// Uh, Java like maybe?
namespace frozen com_google_fabulous_stuff_v1
{
// Yipes! This could get extra tricky
namespace thawed other_nested_junk
{
struct PainfulToUse
{
};
}
}
// Would this even make sense?
namespace frozen WizzyTool {
namespace thawed Module_Like_DLL_so_or_static_lib {
namespace frozen SeparateOptionalSubLibraryFromAnotherHeader {
namespace frozen ExtraSubSubLibraryNeededONLYForAdvancedUsers {
}
}
}
}
[begin soap box mode]在我使用过的项目中,人们已经做了大量的名称空间嵌套,这种东西很快就会过时。感谢c++ 11的使用(尽管没有模板<>的好处,类型定义几乎可以得到相同的东西)。
// Promote JUST the class_name into the scope Likely a method,
// 'translation unit', class body or function.
//
template<typename x1,typename x2>
using mapish = Some::Really::Deeply::Nested::mapish<x1,x2>;
// or in some cases this is nice:
template<typename x1>
using mapish_int = Some::Really::Deeply::Nested::mapish<x1,int>;
mapish_int<bool>::iterator x = ...
或
// Way too much typing and (IMO) harder to read.
// Counter argument is that the explicit scoping makes maintenance easier.
// Wanna debate tabs v spaces too?
Some::Really::Deeply::Nested::class_name<bool,int>::iterator x = ...
来自一个未具名供应商的特定项目使用第二种技术将导致许多函数,即使是慷慨的120列"标准"也会使成员声明变得痛苦。[结束soap_box_mode]
所以,就在这里吐槽吧。即使它是可行的。(从技术上讲,这只是一个挑战。)你愿意这样做吗?(那些从Java或c#开始的人可能已经习惯了这种风格,没有它似乎很痛苦。)我不讨厌它,但是要强制使用c++的所有历史遗产是很困难的。头文件定义ABI(应用程序二进制接口)的想法已经深深植根于C和c++标准中,并且除了声明之外还有大量的尾部。
在大多数情况下,名称空间是一种"幸运的hack"(在我看来,但仍然很有创意!),因为它们真的"只是"改变了初始编译(以及随后的编译/链接)期间的名称混乱,而不是其他。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 将图像添加到资源文件夹UWP C++
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题