C++17 填充和提升

c++17 polyfills and boost

本文关键字:填充 C++17      更新时间:2023-10-16

添加到最近的ISO C++标准中的一些新功能最初是boost的一部分。 这自然提出了编写可移植代码的准则问题。

在使用旧版本的标准时,是否有一种规范的方式来移植使用新的语言功能?

如果您已经在使用 boost,您应该继续使用 boost 版本还是 C++17 中的版本或实验版本?

在尝试便携方面,您应该走多远?

我很惊讶没有在某处找到这个问题作为常见问题解答。 在核心指南、提升常见问题解答和/或作为 ISO 委员会文件中不应该有一些关于这一点的内容吗?

似乎有关于个别特征的问题,但很少考虑更广泛的观点。 例如:

  • C++11 多边形填充物
  • 别名提升::变体
  • 或标准::变体不可编译
  • 如何将填充功能正确插入标准?

有几个项目提供填充代码。 Boost不是唯一的选择,尽管它可能是最常见和最全面的。 还有其他的,例如:

  • https://github.com/tcbrindle/cpp17_headers
  • https://www.reddit.com/r/cpp/comments/5oz3zj/c_shims_library/
  • https://abseil.io/about/philosophy

您可以使用 using 子句导入适当的版本,但这有风险,因为它掩盖了语义差异 另请参阅:

从 boost 到 std::实验和 c++17

您可以考虑使用功能测试宏 并创建像">cxx17/optional.hpp"这样的标头,其中包含:

#ifdef __cpp_lib_experimental_optional
#include <experimental/optional>
namespace cxx17
{
using std::experimental::optional;
}
#elif __cpp_lib_optional
#include <optional>
namespace cxx17
{
using std::optional;
}
#else
#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}
#endif

然而,这仍然掩盖了语义差异。 在某些情况下,提升库故意与标准不同。

您还必须考虑到没有可移植代码这样的东西 仅已移植的代码。您不能保证您的代码会正常工作 除非您在每个环境中实际测试过它。

如果您尝试像这样使代码可移植并且无意 在这些环境中运行它只是一个 YAGNI(您不需要它(。 使用功能测试宏表明你很聪明,但如果不使用它们,则可能会被视为干扰。

如果您已经在使用 boost,那么假设您可以继续使用它似乎是安全的。 并让它给 Boost(和 Boost 维护者(来检测您使用的是 C++17 还是 TS 并按照行事。除非你有很多资源,否则你可以假设 提升库比代码更具可移植性。

要做的一件好事是记录意图。 如果您只是想让未来的维护者的生活更轻松,但您被困在使用 C++11 现在你可以考虑只做(在cxx17/import_optional.hpp中(:

#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}

并使用 cxx17 命名空间指示您希望使用 C++17 但还不能。这也意味着您将 boost 和 ISO 标准之间的偏差视为错误 为您的项目。其他用户可能只是喜欢增强版本。 (例如,考虑 std::variant 和 boost::variant 之间有什么区别?

这主要适用于纯库扩展。 对于语言本身的更改,您有时可以使用宏来模拟它们。这可能很丑陋,所以最好坚持给定的标准。

这可能应该是一个社区维基,但我会等待,以防更有学问的大师提出更好的答案。