我有一个目前使用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。实验性特征是否容易发生重大变化,使其不可靠?
也许还有更多值得怀疑的事情。我为什么要或不应该使用它们?我对一个新项目感到困惑,不知道该决定什么。
答案 0 :(得分:78)
- 是否保证所有兼容编译器都具有相同的实验功能?
醇>
不,实验性功能是可选的。
- 实验性特征是否容易发生重大变化,使其不可靠?
醇>
是的,C ++委员会甚至可能决定放弃某个功能,或者在标准化过程中可能会出现一个会导致功能发生变化的缺陷。
一般来说,依靠实验性功能并不是一个好主意。实验特征正是这个词所说的(即,试验)。
答案 1 :(得分:50)
观众中有人在“C ++标准库”面板中提出了一个问题"在CppCon 2016(YouTube)上谈论名称experimental
可能会吓到用户远离命名空间内的任何内容:
Michael Wong(SG5和SG14的主席以及Concurrency TS的编辑)首先提出了这个问题:你们是否认为[
std::experimental
命名空间]的内容已经准备就绪,这是一个可以做出的论点,它可以为未来3年的生产做好准备,也许你可能要在3年后改变你的代码吗?
我认为委员会内部已经达成了强烈的共识,即实际上是生产就绪。正如我之前所说,在大多数情况下,其中99%会被空投。我们希望确保它不会妨碍您使用它。您可以理解为什么我们希望在这样的上下文中放置大功能,大型功能组,以便它不会干扰整个库系统的其余部分,但它也使您更容易使用它。现在,您可以使用Concept的特定标志打开GCC,这实际上使您可以更轻松地将其分段。
Alisdair Meredith(LWG前任主席)随后跟进:
我会在这里采取相反的立场。 Herb [Sutter]作为标准组织WG21的召集人之一说,当我们走出TSes的道路时,他并不认为TSes会成功,直到我们未能带来一些东西,因为这意味着我们还没有足够的实验性,所以我们在使用TS的时候并不够雄心勃勃。我们确实希望
experimental
能够提示,是的,这些事情可能会发生变化,我们不会对此产生约束,我们可能会犯错误。这是为了降低我们认为具有雄心和实现目标的事物的障碍[...]现在标准似乎是在三年的发布周期中,我们应该更加雄心勃勃地实现真正的实验性功能进入TS,也许更快地将事情推进到主要标准本身。但同样,这将是我们在接下来的几次[C ++标准委员会]会议上讨论的有趣话题。
Stephan T. Lavavej(微软STL实施的维护者)最后回复:
区分界面的实验性和实施的实验性是很重要的,因为当你说'生产就绪'时,这意味着什么?通常,"生产准备就绪",你会想到谈论实施。实现[{1}}]中的某些内容绝对是绝对可靠的。 [...]像TR1中的
std::experimental
标题,[它]在TR1中确实非常非常好,你可以有一个绝对防弹的实现,但它转过来了如果我们知道我们现在所做的事情,那么界面会在[C + + 11发布之前]大幅度变化,那么输入<random>
对于那些人来说是一个更好的信号, &#34;嘿,也许你不想使用experimental
因为,哈哈,它会在C ++ 11&#34;中消失。
因此,似乎标准库开发人员和委员会成员之间有一些愿望,至少在未来,std::experimental::variate_generator
命名空间的内容应该是真正的&#34;实验性的&#34;在本质上,std::experimental
中的某些内容不应被视为C ++标准。
不,据我所知,标准库供应商是否为std::experimental
内的各种功能提供了实现。
答案 2 :(得分:28)
&#34;实验&#34;这是一个有点夸张的术语。 filesystem
库起源于Boost,在提交给ISO之前经过了几次迭代。
但是,ISO标准有意非常保守。称之为实验意味着ISO明确不承诺命名将是稳定的;很明显,您需要在将来的某个时间重新解决您的代码问题。但是知道ISO,很可能会有如何指导。
至于编译器之间的兼容性,期望它是合理的。但是会出现极端情况(例如,考虑Windows驱动器相对路径),这正是未来标准可能会破坏现有代码的原因。理想情况下,当且仅当您依赖于该角落情况时,它才会破坏您的代码,但这不是保证。
答案 3 :(得分:8)
也许还有更多值得怀疑的事情。
要考虑几点:
您的项目如何实现多平台?如果只涉及一个编译器,那么您可以检查其实现和跟踪记录来决定。或者问他们!
您的代码库有多大?变化的影响有多大?
您的项目的基础是API /库/功能提供的功能吗?
有哪些替代方案?
experimental::
一样简单,也可能像强制解决方法一样难。experimental
一个失败或消失,则有boost :: filesystem(resp.boost :: asio)作为替代或回退。