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