现代 C++ 的实验特性对于长期项目是否可靠?
Are the experimental features of modern C++ reliable for long-term projects?
我有一个项目目前使用 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。实验性功能是否容易发生重大变化而变得不可靠?
也许还有更多值得思考的事情。为什么我应该或不应该使用它们?我对一个新项目感到困惑,不知道该做什么决定。
"Experimental"是一个稍微夸张的词。 filesystem
库起源于 Boost 并在那里经历了几次迭代,然后才提交给 ISO。
但是,ISO 标准有意非常保守。称其为实验性意味着 ISO 明确不承诺命名将是稳定的;很明显,您将需要在将来的某个时间重新处理您的代码。但是了解ISO,很可能会有指导。
至于编译器之间的兼容性,希望它是合理的。但是会有极端情况(例如 Windows 驱动器相对路径),这正是未来标准可能会破坏您现有代码的原因。理想情况下,当且仅当您依赖于那个极端情况时,它才会破坏您的代码,但这并不能保证。
- Is it guaranteed that all compliant compilers have the same experimental features?
否,实验性功能是可选的。
- Are experimental features prone to big changes that make them unreliable?
是的,C++ 委员会甚至可能决定放弃某个功能,或者在标准化过程中可能会出现一个缺陷,从而迫使某个功能发生变化。
一般来说,依赖实验性功能并不是一个好主意。实验性功能正是这个词所说的(即进行实验)。
在 CppCon 2016 (YouTube) 的 "C++ Standard Library Panel" 演讲中,听众中有人提出了一个问题,即 experimental
这个名字可能会吓跑用户使用命名空间:
Do you guys consider [the contents of the std::experimental
namespace] production ready and is that an argument that can be made, [that] it's effectively production ready for the next 3 years, and maybe you have to change your code 3 years later, maybe?
Michael Wong(SG5 和 SG14 的主席以及 Concurrency TS 的编辑)首先回答了问题:
I think there's strong consensus within the committee that it is practically production ready. As I said before, in most cases 99% of it gets air-dropped in. We want to make sure that it's not an impediment for you to use it. You can understand why we want to put big features, large groups of features, in such a context, so that it doesn't disturb the rest of the whole library system, but it also makes it easier for you to use it. Now you can turn on GCC with a specific flag for Concepts, you know, that actually makes it easier for you to segment it out.
Alisdair Meredith(LWG 前任主席)随后跟进:
I'm going to take the contrary position here. One of the things Herb [Sutter] said as convener of WG21, the standard group, when we set off down the path of TSes is, he didn't think that TSes will have succeeded until we have failed to bring something forward, because it means we're not being experimental enough, we're not being ambitious enough in what we're using the TSes for. We really do want that experimental
to be a hint that, yes, these things are subject to change, we're not binding to that, and we can get things wrong. This is to lower our barrier for the things we consider to be as ambitious and reach as we can [...] Now the standard seems to be on a three-year release cycle, we should be much more ambitious in putting really experimental features into the TS, and perhaps advancing things more rapidly into the main standard itself. But again, this will be a fun topic for us to discuss at the next few [C++ standard committee] meetings.
Stephan T. Lavavej(Microsoft 的 STL 实施维护者)最后回复:
It's important to draw a distinction between the experimentalness of interface and the experimentalness of the implementation, because when you say "production ready", what does that mean? Usually, "production ready", you would think of that talking about the implementation. It's quite possible for an implementation [of something in std::experimental
] to be absolutely [...] bulletproof. [...] Something like [...] the <random>
header in TR1, [it was] really, really nice in TR1, and you could have had an absolutely bullet-proof implementation of that, but it turned out that the interface churned substantially [before the release of] C++11 and [...] if we knew back then what we do now, putting in an experimental
would have been a better signal to people that, "Hey, maybe you don't want to use std::experimental::variate_generator
because, ha-ha, it's going to disappear in C++11".
所以标准库开发人员和委员会成员似乎希望,至少在未来,std::experimental
命名空间的内容应该是真正的 "experimental",并且不应想当然地认为 std::experimental
中的内容会进入 C++ 标准。
不,据我所知,标准库供应商是否提供 std::experimental
中各种功能的实现取决于标准库供应商。
Maybe there's more things to wonder about.
需要考虑的几点:
您的项目有多平台化?如果只涉及一个编译器,那么您可以检查其实现和跟踪记录来决定。或者问他们!
您的代码库有多大?变化的影响有多大?
API/library/feature 提供的功能对您的项目有多重要?
有哪些选择?
- 使用实验性功能,然后使代码适应修改 when/if 它变得标准化。可能就像删除
experimental::
一样简单,也可能像强制解决方法一样困难。
- 添加一个抽象层(Serge Ballesta 评论)。如果实验性功能发生变化,您的重写将被隔离。对于标准功能,它可能有点矫枉过正(std::filesystem 已经是一个抽象层...)。
- 使用另一个 API/library。同样的问题:成熟度?鲁棒性?稳定?可移植性?使用方便?功能?
- 在 std::filesystem(或网络 TS)的情况下,有 boost::filesystem(resp. boost::asio)作为替代或回退,以防
experimental
一个失败或消失。
我有一个项目目前使用 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。实验性功能是否容易发生重大变化而变得不可靠?
也许还有更多值得思考的事情。为什么我应该或不应该使用它们?我对一个新项目感到困惑,不知道该做什么决定。
"Experimental"是一个稍微夸张的词。 filesystem
库起源于 Boost 并在那里经历了几次迭代,然后才提交给 ISO。
但是,ISO 标准有意非常保守。称其为实验性意味着 ISO 明确不承诺命名将是稳定的;很明显,您将需要在将来的某个时间重新处理您的代码。但是了解ISO,很可能会有指导。
至于编译器之间的兼容性,希望它是合理的。但是会有极端情况(例如 Windows 驱动器相对路径),这正是未来标准可能会破坏您现有代码的原因。理想情况下,当且仅当您依赖于那个极端情况时,它才会破坏您的代码,但这并不能保证。
- Is it guaranteed that all compliant compilers have the same experimental features?
否,实验性功能是可选的。
- Are experimental features prone to big changes that make them unreliable?
是的,C++ 委员会甚至可能决定放弃某个功能,或者在标准化过程中可能会出现一个缺陷,从而迫使某个功能发生变化。
一般来说,依赖实验性功能并不是一个好主意。实验性功能正是这个词所说的(即进行实验)。
在 CppCon 2016 (YouTube) 的 "C++ Standard Library Panel" 演讲中,听众中有人提出了一个问题,即 experimental
这个名字可能会吓跑用户使用命名空间:
Do you guys consider [the contents of the
std::experimental
namespace] production ready and is that an argument that can be made, [that] it's effectively production ready for the next 3 years, and maybe you have to change your code 3 years later, maybe?
Michael Wong(SG5 和 SG14 的主席以及 Concurrency TS 的编辑)首先回答了问题:
I think there's strong consensus within the committee that it is practically production ready. As I said before, in most cases 99% of it gets air-dropped in. We want to make sure that it's not an impediment for you to use it. You can understand why we want to put big features, large groups of features, in such a context, so that it doesn't disturb the rest of the whole library system, but it also makes it easier for you to use it. Now you can turn on GCC with a specific flag for Concepts, you know, that actually makes it easier for you to segment it out.
Alisdair Meredith(LWG 前任主席)随后跟进:
I'm going to take the contrary position here. One of the things Herb [Sutter] said as convener of WG21, the standard group, when we set off down the path of TSes is, he didn't think that TSes will have succeeded until we have failed to bring something forward, because it means we're not being experimental enough, we're not being ambitious enough in what we're using the TSes for. We really do want that
experimental
to be a hint that, yes, these things are subject to change, we're not binding to that, and we can get things wrong. This is to lower our barrier for the things we consider to be as ambitious and reach as we can [...] Now the standard seems to be on a three-year release cycle, we should be much more ambitious in putting really experimental features into the TS, and perhaps advancing things more rapidly into the main standard itself. But again, this will be a fun topic for us to discuss at the next few [C++ standard committee] meetings.
Stephan T. Lavavej(Microsoft 的 STL 实施维护者)最后回复:
It's important to draw a distinction between the experimentalness of interface and the experimentalness of the implementation, because when you say "production ready", what does that mean? Usually, "production ready", you would think of that talking about the implementation. It's quite possible for an implementation [of something in
std::experimental
] to be absolutely [...] bulletproof. [...] Something like [...] the<random>
header in TR1, [it was] really, really nice in TR1, and you could have had an absolutely bullet-proof implementation of that, but it turned out that the interface churned substantially [before the release of] C++11 and [...] if we knew back then what we do now, putting in anexperimental
would have been a better signal to people that, "Hey, maybe you don't want to usestd::experimental::variate_generator
because, ha-ha, it's going to disappear in C++11".
所以标准库开发人员和委员会成员似乎希望,至少在未来,std::experimental
命名空间的内容应该是真正的 "experimental",并且不应想当然地认为 std::experimental
中的内容会进入 C++ 标准。
不,据我所知,标准库供应商是否提供 std::experimental
中各种功能的实现取决于标准库供应商。
Maybe there's more things to wonder about.
需要考虑的几点:
您的项目有多平台化?如果只涉及一个编译器,那么您可以检查其实现和跟踪记录来决定。或者问他们!
您的代码库有多大?变化的影响有多大?
API/library/feature 提供的功能对您的项目有多重要?
有哪些选择?
- 使用实验性功能,然后使代码适应修改 when/if 它变得标准化。可能就像删除
experimental::
一样简单,也可能像强制解决方法一样困难。 - 添加一个抽象层(Serge Ballesta 评论)。如果实验性功能发生变化,您的重写将被隔离。对于标准功能,它可能有点矫枉过正(std::filesystem 已经是一个抽象层...)。
- 使用另一个 API/library。同样的问题:成熟度?鲁棒性?稳定?可移植性?使用方便?功能?
- 使用实验性功能,然后使代码适应修改 when/if 它变得标准化。可能就像删除
- 在 std::filesystem(或网络 TS)的情况下,有 boost::filesystem(resp. boost::asio)作为替代或回退,以防
experimental
一个失败或消失。