[英]Inject namespace experimental to std
将命名空间std::experimental
注入到std
是不是很好或很好的parctice?
namespace std
{
namespace experimental
{
}
using namespace experimental;
}
#include <experimental/optional>
int main()
{
std::optional< int > o;
return 0;
}
甚至以更现代的形式:
#if __has_include(<optional>)
# include <optional>
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
namespace std
{
using namespace experimental;
}
#else
#error !
#endif
int main()
{
std::optional< int > o;
return 0;
}
引入std::experimental
“sub-namespace”的意图很明确,因为std::experimental
目前包含大量新库 。 我认为它们很可能会在没有任何实质性更改的情况下迁移到namespace std
,并且当前编写的用户代码可以依赖于此(我完全错了吗?)。 否则,所有这些代码应该被重构,以从改变std::experimental::
以std::
在未来。 这不是什么大不了的事,但可能有理由不这样做。
问题是关于生产代码和不太严肃的代码。
在工作中,我花了很多时间来对抗这种投机复杂性(我正在寻找一个表征行为特征的好短语,这是迄今为止我提出的最好的)。
在我看来,你现在引入复杂性和风险到您的代码,以避免在未来重构。 这已经足够糟糕,但在这种特殊情况下,我甚至会说重构是一个糟糕的单词选择 - 它不是简单的文本替换重构。
通过代码删除std :: experimental's(或者更改为std ::或std :: something_else)实际上只是一个文本替换。 在最好的情况下,您正在编辑或ide中查看快速命令。 在最糟糕的情况下,你正在考虑花几个小时写一个正则表达式 - 可能在你的编辑器中,也许在PERL或Ruby ...
那些std :: experiment表示你正在使用实验性功能,并且在你的代码中有一个明确的声明是很好的。 如果某些图书馆进入标准,合格的程序员可以快速轻松地进行必要的文本替换。 如果您的文本编辑技能不能胜任任务,请不要破解语言 - 提高文本编辑技能。 这是一个机会。
更通俗地说,编写最简单,最干净的代码,满足您现在的需求,并随时准备好在情况发生变化时进行更改。 这通常会产生更灵活的代码,比现在的推测更能支持您真正的未来需求。
听起来不错。
首先,这是未定义的行为。 N4140标准草案说:
[namespace.std]/1:
如果其添加声明或定义到命名空间一个C ++程序的行为是未定义std
命名空间内或一个命名空间std
除非另有规定。 [...]
using-directive是一种声明,因此UB是当天的订单。
其次, std::experimental
中的东西很容易改变。 您可能会发现,当事物被移动到std
,您的代码仍会编译,但不会以完全相同的方式操作。 这只是一个问题,特别是在生产代码中。
你正在做的是介绍未定义的行为。 一般而言,我认为引入不明确的行为更多地落入坏习惯的范畴,而不是良好实践的范畴。
根据1998 C ++标准,第17.4.3.1节,第1段。
除非另有说明,否则C ++程序未定义向命名空间std中的命名空间std或命名空间添加声明或定义。 程序可以将任何标准库模板的模板特化添加到命名空间std。 标准库模板的这种特化(完整或部分)会导致未定义的行为,除非声明取决于用户定义的外部链接名称,除非特化符合原始模板的标准库要求。
我没有更新版本的标准(在我当前的机器上)但是,从内存来看,C ++标准的所有版本都有类似的条款。
std::experimental
许多库可以并且将会在迁移到std
之前以破坏用户代码的方式进行更改,并且它们甚至可能无法迁移到std
。 这就是为什么他们把它们放在std::experimental
。
std::experimental
旨在用于相对自由的所有地方,您可以为C ++引入新的提议库功能,编译器可以实现它们,而不会破坏现有代码。 实施是不稳定的,不是标准的。 他们中的一些可能会进入C ++ 1z,但其中一些可能没有,而那些确实可以改变的那些可能会被改变,而那些没有进入它的那些可能会使它成为C ++ 2x并带来实质性的改变。
简单地看一下Ranges的历史。 或者微软正在提议的协程/可恢复功能。 或反思工作组。 或概念。
我敢说,这次迭代的C ++的目标是敏捷,快速失败。 许多独立提案通过管道工作,目标是最小化相互依赖性。 如果给定的提议在C ++标准时尚未准备好进入黄金时间,那么它就不会进入。如果它准备就绪,并且值得,它将以模块方式添加。
这是(据我的理解)明确做到的,以避免混乱,其中一些过程的部分“太大而不能失败”和那些没有准备好的地方发布到标准,或标准版本被推迟多年因为某些事情不是准备。
除此之外,以这种方式搞乱std
会使你的程序形成错误而不需要诊断,正如其他答案所指出的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.