现代C ++的实验性特征对于长期项目是否可靠?

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

 #ifdef CXX17 //if this is C++17 std::filesystem::something ...; #else std::experimental::filesystem::something ...; #endif 

我的顾虑是:

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

2.实验性function是否容易发生大的变化,使其变得不可靠?

也许还有更多的事情要考虑。 为什么我应该或不应该使用它们? 我对一个新项目感到困惑,不知道该怎么做。

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

不,实验function是可选的。

  1. 实验性function是否容易发生大的变化,使得它们变得不可靠?

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

一般来说,依靠实验性的function并不是一个好主意。 实验function正是这个词所说的(即,试验)。

观众中有人在CppCon 2016( YouTube )的“C ++标准库面板”演讲中提出了一个问题:名称experimental的潜在可能性使用户无法使用名称空间中的任何内容:

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

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

我认为委员会内部已形成强烈的共识,即实际上已经准备就绪。 正如我之前所说的,在大多数情况下,有99%的空气会被空气污染。我们要确保它不会阻碍你使用它。 你可以理解为什么我们要在这样的背景下放置大的function,大量的function,这样它就不会干扰整个图书馆系统的其余部分,但它也使你更容易使用它。 现在,您可以打开GCC,为Concepts指定一个特定的标志,这样可以使您更容易将其细分。

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

我将在这里采取相反的立场。 Herb(Sutter)作为标准组WG21的召集人说,当我们开始TSes的道路时,他不认为TSes会成功,直到我们没有带来前进的东西,因为它意味着我们没有足够的实验经验,我们没有足够的雄心,我们正在使用TSes。 我们确实希望这个experimental是一个暗示,是的,这些东西都是可以改变的,我们并不拘泥于此,我们可以把事情弄错。 这是为了降低我们所认为的雄心勃勃的障碍,并尽可能达到我们现在的标准似乎是在三年的发布周期,我们应该更雄心勃勃地把真正的实验function进入TS,也许更快地把事情推进到主要标准本身。 但是,再次,这将是我们在接下来的几次[C ++标准委员会]会议上讨论的一个有趣的话题。

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

在界面的实验性和实施的实验性之间作出区分是很重要的,因为当你说“生产就绪”时,这意味着什么? 通常情况下,“生产准备”,你会想到那个谈论实施。 std::experimental某个实现是完全可以实现的。 […]像TR1中的<random>标题,TR1真的非常好,你可以有一个绝对的防弹的实现,但事实certificate,界面在C ++ 11发布之前就大幅度地搅动了,如果我们现在知道了我们现在正在做的事情,那么进行experimental对于人们来说是一个更好的信号:“嘿,也许你不会不想使用std::experimental::variate_generator因为,哈哈,它将在C ++ 11中消失“。

因此,标准图书馆开发者和委员会成员希望,至less将来, std::experimental命名空间的内容本质上应该是“实验性的”,不应该被视为理所当然std::experimental中的某些东西将会使其成为C ++标准。

不,据我了解,标准库供应商是否提供了std::experimental各种function的实现。

“实验”是一个稍微夸张的术语。 filesystem库起源于Boost,并在提交给ISO之前经过了几次迭代。

但是,ISO标准故意非常保守。 把它称为实验手段,ISO明确地不承诺命名将是稳定的; 很明显,您将来需要重新编写代码。 但是了解ISO,很可能会有指导。

至于编译器之间的兼容性,期望它是合理的。 但是会有一些特殊的情况(比如Windows驱动相对path),这就是为什么未来的标准可能会破坏现有的代码。 理想情况下,只有当你依赖这个angular落的情况下,它会打破你的代码,但这不是一个保证。

也许还有更多的事情要考虑。

有几点需要考虑:

  • 多平台是你的项目? 如果只涉及一个编译器,那么你可以检查它的实现和跟踪logging来决定。 或者问问他们!

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

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

  • 有什么select?

    • 使用实验性function,然后在代码变为标准化时将代码修改为修改。 可能会像删除experimental::一样简单,或者像强迫解决方法一样困难。
    • 添加一个抽象层(Serge Ballesta评论)。 如果实验function发生变化,则重新写入是孤立的。 对于一个标准的function,它可能是矫枉过正(std :: filesystem已经是一个抽象层…)。
    • 使用另一个API /库。 同样的问题:成熟? 稳健性? 稳定性? 可移植性? 使用方便? 特征?
  • 在std :: filesystem(或者networkingTS)的情况下,boost :: filesystem(boost :: asio)作为替代或者备用,以防experimental失败或者消失。