【发布时间】:2021-03-01 01:33:44
【问题描述】:
有人知道为什么在我的 Visual Studio 2012 c++ 项目中__cplusplus 被定义为199711L(这是“旧”C++)吗?它不应该说201103L,因为 VS 2012 现在支持 C++ 11 吗?即使我包含 C++ 11 头文件,它仍然是错误定义的。有什么线索吗?
【问题讨论】:
标签: c++ visual-studio visual-c++ c++11
有人知道为什么在我的 Visual Studio 2012 c++ 项目中__cplusplus 被定义为199711L(这是“旧”C++)吗?它不应该说201103L,因为 VS 2012 现在支持 C++ 11 吗?即使我包含 C++ 11 头文件,它仍然是错误定义的。有什么线索吗?
【问题讨论】:
标签: c++ visual-studio visual-c++ c++11
【讨论】:
make_unique 添加到库中,因为它不需要时间。您还将了解到,MS 正在为标准化开创几项工作,例如 async/await 提案,因此他们也将其列为优先事项,以便我们有一个可行的实施来完善我们的想法/提案。不是他们选择实施什么,而是他们选择何时实施。
这实际上取决于您期望该宏的实际含义。 201103L 是否应该表示“此编译器完全支持编译器和库中的所有 C++11?”它应该意味着“这个编译器支持一些合理的 C++11 子集吗?”是否应该表示“此编译器以某种方式、形状或形式支持至少一个 C++11 功能?”
实际上由每个实现来决定何时增加版本号。 Visual Studio 与 Clang 和 GCC 不同,它没有单独的 C++03 编译模式;它提供了一组特定的功能,这就是它所提供的。
一般来说,单个宏不是决定何时使用某些功能的有用工具。 Boost.Config 是一种更可靠的机制。在标准的未来版本中,标准委员会是investigating ways of dealing with this problem。
【讨论】:
我和 Nicol 在这件事上。测试__cplusplus >= 201103L 的唯一原因是检查您是否可以使用新功能。如果编译器只实现了一半的新特性,但使用了__cplusplus 的新值,它将无法编译许多受__cplusplus >= 201103L 保护的有效C++11 代码(我有一些使用thread_local 和@ 987654325@ 参考)。另一方面,如果它保留199711L,它将使用安全的 C++98 代码,这仍然可以。这样可能会错过一些优化,但您仍然可以使用其他方法来检测特定功能是否可用(编译器版本、编译器特定宏,如 __GXX_EXPERIMENTAL_CXX0X__、为您检查编译器宏的 boost 宏等)。重要的是安全的默认设置。
切换到 __cplusplus 的新值有 2 个可能的原因:
据我所知,所有切换的编译器都属于第二类。
我相信一些编译器供应商对改变 __cplusplus(最容易实现的 C++11 功能,良好的宣传)的价值过于热情,有些人更保守是好的。
【讨论】:
截至 2018 年 4 月,MSVC 2017 现在可以正确报告宏,但前提是使用特定开关 (/Zc:__cplusplus)。这是因为很多旧代码依赖于检测 MSVC 编译器的宏的旧值。 来源:https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
希望将来,一旦全世界的人们更新了他们的代码,MS 将默认正确报告宏。
【讨论】:
/Zc:__cplusplus 添加到项目命令行选项中)。如果您依赖__cplusplus,请添加命令行开关。如果您仅在 Windows 上使用 Visual Studio,则 _MSVC_LANG 宏可能更合适,因为它会根据所选的 C++ 标准进行更改。由于有一种解决方法,微软似乎不太可能在这方面做出让步。