【问题标题】:Is '_HAS_CXX17' macro usable in custom project headers to enable C++17 language set features?'_HAS_CXX17' 宏是否可用于自定义项目标头以启用 C++17 语言集功能?
【发布时间】:2019-02-22 01:21:36
【问题描述】:

我想创建使用标准 C++ 中的“可选”的标头。 但是,我的标头将引用自 Visual Studio 2015 以及 Visual Studio 2017 项目。

我想要一些东西,例如对于 Visual Studio 2017(带有 C++ 17 语言功能集),使用 std::optional 并且对于 Visual Studio 2015,使用 boost::optional。

我在想这样的事情:

#include <yvals.h>
#if _HAS_CXX17
 #include <optional>
 template <typename T> using Optional = std::optional<T>;
#else
 #include "boost/optional/optional.hpp"
 template <typename T> using Optional = boost::optional<T>;
#endif

这样使用'_HAS_CXX17'宏可以吗? 有更好的方法吗?

【问题讨论】:

标签: c++ visual-studio-2017 boost-optional stdoptional


【解决方案1】:

简短的回答是:在 Visual C++ 运行时的实现中依赖内部预处理器定义是不安全的,从技术上讲,所有以单个 _ 开头的编译器符号都保留给由实现使用。

例如,_NOEXCEPT 已在 Visual Studio 2015 和 2017 内部使用,但从 VS 2017(15.8 更新)开始,此宏不再存在;标头直接使用noexcept

使用__has_include 的建议很好,但在 VS 2017(15.3 更新)之前不受支持。

另一个挑战是__cplusplus 并不表示您正在使用/std:c++17,除非您使用带有默认关闭的新/Zc:__cplusplus 开关的VS 2017(15.7 更新)。

在一系列 VS 版本中执行此操作的最安全方法可能是:

#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L) && (_MSC_VER >= 1913))
#if __has_include(<optional>)
 #include <optional>
 template <typename T> using Optional = std::optional<T>;
#else
 #include "boost/optional/optional.hpp"
 template <typename T> using Optional = boost::optional<T>;
#endif
#else
 #include "boost/optional/optional.hpp"
 template <typename T> using Optional = boost::optional<T>;
#endif

Visual C++ Language Conformance

【讨论】:

  • MSVC 是否定义了feature test macros
  • 公平地说,委员会直到 C++20 才定义功能测试宏 :( 见 P0096r5
  • 谢谢@ChuckWalbourn。我担心的一件事是,如果我们检查了 _MSVC_LANG >= 201703L,那么为什么我们需要检查 _MSC_VER?
  • _MSVC_LANG &gt;= 201703L 测试表明它是带有/std:c++17 的Microsoft Visual C++ 或不带/Zc:__cplusplus/std:c++latest。在尝试使用__has_include 之前,您仍然需要确保它是 VS 2017(15.3 更新)或更高版本。在 __cplusplus &gt;= 201703L 的情况下,则它是 VS 2017(15.7 更新)或更高版本,已经使用 /Zc:__cplusplus 或其他一些 C++17 标准编译器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
相关资源
最近更新 更多