现代C++的实验性功能是否可靠用于长期项目?

The*_*ist 84 c++ portability c++-standard-library c++11 c++17

我有一个目前使用C++ 11/14的项目,但它需要类似的东西std::filesystem,它只在C++ 17中可用,因此我没有机会当前使用它.但是,我看到它在我当前的编译器中可用std::experimental::filesystem.使用实验性功能是一个好主意,假设我将来可以添加如下内容:

#ifdef CXX17 //if this is C++17
std::filesystem::something ...;
#else
std::experimental::filesystem::something ...;
#endif
Run Code Online (Sandbox Code Playgroud)

我担心的是:

1.是否保证所有兼容编译器具有相同的实验功能?

2.实验性特征是否容易发生重大变化,使其不可靠?

也许还有更多值得关注的事情.我为什么要或不应该使用它们?我对一个新项目感到困惑,不知道该决定什么.

101*_*010 79

  1. 是否保证所有兼容的编译器都具有相同的实验功能?

不,实验性功能是可选的.

  1. 实验性特征是否容易发生重大变化,使其不可靠?

是的,C++委员会甚至可能决定放弃某个功能,或者在标准化过程中可能会出现一个会导致功能发生变化的缺陷.

一般来说,依靠实验性功能并不是一个好主意.实验特征正是这个词所说的(即,试验).

  • @TheQuantumPhysicist:"已经接受"是一个棘手的概念.任何时候都可以通过接受更改删除它来删除任何东西,这已经发生在每个标准上.您可能希望在功能集合理可靠之前至少等到国际标准草案. (14认同)
  • @KerrekSB:我几乎是C++ 03的荷兰国家机构;).我们有一个SC22的国家秘书,它知道ISO程序以及如何回复FDIS,但不知道什么.除了我们的WG14代表Randy Marques之外,我们的SC22代表都不了解C++.兰迪只是嘲笑这样一个事实:C++需要更多的页面来定义它所有的UB而不是定义行为所需的C - 不希望他回复那个FDIS;) (4认同)
  • 请参阅第二点,请注意我正在谈论已经被接受的功能,但*可能*会有所不同. (2认同)

Jos*_*son 50

观众中有人在CppCon 2016(YouTube)的"C++标准库面板"演讲中提出了一个问题,即该名称experimental可能会吓到用户远离命名空间内的任何内容:

你们是否认为[ std::experimental命名空间] 的内容已经准备就绪,这是一个可以做出的论点,它可以为未来3年的生产做好准备,也许你必须在3年后改变你的代码,也许吧?

Michael Wong(SG5和SG14的主席以及Concurrency TS的编辑)首先提出了这个问题:

我认为委员会内部已经达成了强烈的共识,即实际上是生产准备就绪.正如我之前所说,在大多数情况下,其中99%会被空投.我们希望确保它不会妨碍您使用它.您可以理解为什么我们希望在这样的上下文中放置大功能,大型功能组,以便它不会干扰整个库系统的其余部分,但它也使您更容易使用它.现在,您可以使用Concept的特定标志打开GCC,实际上,您可以更轻松地将其分段.

Alisdair Meredith(LWG的前任主席)随后跟进:

我将在这里采取相反的立场.Herb [Sutter]作为标准组织WG21的召集人之一说,当我们走出TSes的道路时,他认为TSes不会成功,直到我们未能带来前进的东西,因为它意味着我们没有足够的实验性,我们在使用TSes时没有足够雄心勃勃.我们真的希望这experimental是一个提示,是的,这些事情可能会发生变化,我们对此没有约束力,我们可能会犯错误.这是为了降低我们认为具有雄心和实现目标的事物的障碍[...]现在标准似乎是在三年的发布周期中,我们应该更加雄心勃勃地实现真正的实验性功能进入TS,也许更快地将事情推进到主要标准本身.但同样,这将是我们在接下来的几个[C++标准委员会]会议上讨论的有趣话题.

Stephan T. Lavavej(微软STL实施的维护者)最后回应:

重要的是要区分界面的实验性和实现的实验性,因为当你说"生产就绪"时,这意味着什么?通常,"生产就绪",你会想到谈论实施.[某物std::experimental] 的实施很可能绝对是防弹的.[...]像<random>TR1中的标题,[它]真的,在TR1中非常好,而且你可以有一个绝对的防弹实现,但事实证明界面搅拌实质上[在C++ 11发布之前] [...]如果我们知道我们现在做了什么,那么投入一个experimental本来就更好的信号给人们,"嘿,也许你不想使用std::experimental::variate_generator,因为,呵呵,这将消失在C++ 11" .

如此看来,有标准库的开发者和委员认为,在未来至少,在内容中的一些愿望std::experimental命名空间应该是真正的"实验性"的性质,它不应该被视为理所当然的东西在std::experimental意志使其成为C++标准.

不,据我所知,标准库供应商是否为其中的各种功能提供了实现std::experimental.

  • 在我第一次读到这个名字10年后,微软的STL维护者被命名为STL的事实仍让我轻笑. (45认同)
  • @JörgWMittag你应该遇到他们的编译器维护者Michael Sam Victor Collins (18认同)

MSa*_*ers 28

"实验性"是一个略夸张的术语.该filesystem库起源于Boost,在提交给ISO之前经过了几次迭代.

但是,ISO标准是故意非常保守的.将其称为实验意味着ISO明确不承诺命名将是稳定的; 很明显,您需要在将来的某个时间重新解决您的代码问题.但是知道ISO,很可能会有指导方式.

至于编译器之间的兼容性,期望它是合理的.但是会出现极端情况(例如,考虑Windows驱动器相对路径),这正是未来标准可能会破坏现有代码的原因.理想情况下,当且仅当您依赖于那个角落情况时,它会破坏您的代码,但这不是保证.


Pab*_*o H 8

也许还有更多值得关注的事情.

需要考虑以下几点:

  • 您的项目如何实现多平台?如果只涉及一个编译器,那么您可以检查其实现和跟踪记录来决定.或者问他们!

  • 你的代码库有多大?变化的影响有多大?

  • API /库/功能提供的功能对您的项目有多重要?

  • 有哪些替代方案?

    • 使用实验性功能,然后在代码变得标准化时使代码适应修改.可能像删除一样简单,也可能experimental::像强制解决方法一样难.
    • 添加一个抽象层(Serge Ballesta评论).如果实验性功能发生变化,您的重写将被隔离.对于标准功能,它可能是过度的(std :: filesystem已经是一个抽象层......).
    • 使用其他API /库.同样的问题:成熟度?稳健性?稳定性?可移植性?便于使用?特征?
  • 在std :: filesystem(或网络TS)的情况下,有一个boost :: filesystem(experimentalresp.boost :: asio)作为替代或后备,以防一个失败或消失.