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


87

我有一个当前使用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

我担心的是:

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

2.实验功能是否容易发生重大变化而使其不可靠?

也许还有更多事情想知道。为什么我应该或不应该使用它们?我为一个新项目感到困惑,不知道该怎么决定。


25
实验一词没有回答您的问题吗?
1010年

6
主要是个人喜好,但我会避免使用来使代码混乱#idef CXX17。恕我直言,可移植的方式是将所有文件系统相关的代码放入一个单独的编译单元(可能是一个类),在代码的其余部分中使用它,并以当前的C ++ 11/14标准进行编码。记录为什么要这样写,并在合理的情况下最终在维护阶段将其移植到C ++ 17。(评论原始问题)
Serge Ballesta

4
作为进入标准的候选人只是“实验性的”。这不是代码质量的反映。
Galik '17

5
“实验”版本和最终C ++ 17版本之间有很多更改,请参阅文档P0492R1
Bo Persson

7
filesystem您而言,使用它所带来的风险要比其他事情少得多,因为您已经知道它已在C ++ 17中标准化,并且它的确切C ++ 17规范已公开。因此,您要做的就是确保仅使用experimental::filesystemC ++ 17规范中的功能。当然,您必须知道所有目标平台都支持experimental::filesystemC ++ 17之一std::filesystem
Howard Hinnant

Answers:


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

不,实验功能是可选的。

  1. 实验功能是否容易发生大的变化而使其不可靠?

是的,C ++委员会甚至可能决定放弃某个功能,或者在标准化过程中可能会出现缺陷,从而迫使功能发生更改。

通常,依靠实验功能不是一个好主意。实验功能正是这个词所说的(即要进行实验)。


2
关于第二点,请注意,我所说的是已经接受但可能有所不同的功能。
量子物理学家

14
@TheQuantumPhysicist:“已被接受”是一个棘手的概念。以后可以接受将其删除的更改,因此可以在任何时间删除所有内容,并且这已发生在每个标准中。您可能要至少等到国际标准草案后才能使用该功能集。
Kerrek SB

1
@KerrekSB:您不是说国际标准最终草案(FDIS)吗??起草是一个相当永久的过程。
MSalters

1
@MSalters:不,如果您赶时间的话,DIS可能足够好。而且无论如何这次我们可能没有FDIS。
Kerrek SB

4
@KerrekSB:我几乎是C ++ 03左右的荷兰国家机构;)。我们有一个SC22的国家秘书,他了解ISO程序以及如何答复FDIS,但不知道如何。除了我们的WG14代表Randy Marques之外,我们的SC22代表都不了解C ++。而且Randy只是在取笑一个事实,即C ++比定义行为所需的C需要更多的页面来定义其所有UB-不想让他回复该FDIS;)
MSalters

50

在CppCon 2016(YouTube)上的“ C ++标准库专家组”演讲中,听众中有人提出了一个问题,即该名称可能使experimental用户害怕使用命名空间中的任何内容:

你们是否认为[std::experimental名称空间的内容]生产已经准备就绪,是否可以提出一个论点,[它]在接下来的3年内有效地准备生产,也许您必须在3年后更改代码?

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

我认为委员会内部已经就生产准备就绪达成了强烈共识。正如我之前说过的,在大多数情况下,有99%的空气会掉进去。您可以理解为什么我们要在这样的上下文中放置大型功能,大型功能组,以免打扰整个图书馆系统的其余部分,但也使您更轻松地使用它。现在,您可以使用一个特定的Concepts标志打开GCC,您知道,这实际上使您更容易将其细分。

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

我将在这里采取相反的立场。作为标准工作组WG21的召集人,赫伯[萨特]说的一件事是,当我们确定TSes的发展方向时,他认为TSes不会成功,除非我们未能提出建议。意味着我们还没有足够的实验性,对于我们使用TS的目的没有足够的野心。我们确实希望experimental暗示是的,这些事情可能会发生变化,我们没有约束力,我们可能会出错。这是为了降低我们认为雄心勃勃且可以达到的事物的壁垒。现在,该标准似乎处于三年发布周期,我们应该更加雄心勃勃地投入真正的实验性功能进入TS,也许可以更快地将其推进到主要标准本身。但是,对于我们在接下来的几次[C ++标准委员会]会议上进行讨论,这将是一个有趣的话题。

Stephan T. Lavavej(Microsoft STL实现的维护者)最后回应:

区分接口的实验性和实现的实验性很重要,因为当您说“生产就绪”时,这意味着什么?通常,“准备就绪”时,您会想到有关实现的内容。…中的某些实现完全有可能std::experimental是防弹的。[...]类似于<random>TR1中的标头,在TR1中确实非常好,并且您可能对此有绝对的防弹实现,但事实证明该接口混乱了在[...] C ++ 11发行之前和[...]如果我们早就知道现在该怎么做,则在experimental向人们发出更好的信号时说:“嘿,也许您不想使用std::experimental::variate_generator 因为,哈哈,它将在C ++ 11中消失”。

因此,似乎标准库开发人员和委员会成员之间存在某种愿望,至少在将来,std::experimental命名空间的内容本质上应该是真正的“实验性”,不应将某些std::experimental遗嘱视为理所当然。使其成为C ++标准。

据我了解,不,这取决于标准库供应商是否为其提供各种功能的实现std::experimental


47
在我第一次读这个名字10年之后,微软的STL维护者被命名为STL的事实仍然让我发笑。
约尔格W¯¯米塔格

19
@JörgWMittag,您应该遇到他们的编译器维护者Michael Sam Victor Collins
MM

28

“实验性”是一个稍微夸张的术语。该filesystem库起源于Boost,并在那里进行了几次迭代,然后才提交给ISO。

但是,ISO标准故意非常保守。称其为实验性意味着ISO明确表示不会保证命名会保持稳定。很明显,将来您将需要重新寻址您的代码。但是了解ISO的情况下,很可能会有指导。

至于编译器之间的兼容性,希望它是合理的。但是会有很多情况(例如,考虑Windows驱动器相对路径),这就是为什么将来的标准可能会破坏您现有的代码的原因。理想情况下,当且仅当您依赖于这种极端情况时,它才会破坏您的代码,但这不是保证。


8

也许还有更多事情想知道。

需要考虑的几点:

  • 您的项目有多平台?如果只涉及一个编译器,则可以检查其实现并跟踪记录以确定。或问他们!

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

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

  • 有哪些选择?

    • 使用实验性功能,然后在代码标准化时对其进行修改以适应修改。可能像删除操作一样容易,也可能experimental::像强迫解决方法一样困难。
    • 添加一个抽象层(Serge Ballesta注释)。如果实验性功能更改,您的重写将被隔离。对于标准功能,它可能会过大(std :: filesystem已经是抽象层...)。
    • 使用其他API /库。同样的问题:成熟吗?健壮性?稳定性?可移植性?便于使用?特征?
  • 如果是std :: filesystem(或联网TS),则可以使用boost :: filesystem(或者boost :: asio)作为替代方案或回退,以防experimental失败或消失。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.