“_HAS_CXX17”宏是否可用于自定义项目 headers 以启用 C++17 语言集功能?
Is '_HAS_CXX17' macro usable in custom project headers to enable C++17 language set features?
我想创建 headers,它使用来自标准 C++ 的 'optional'。
但是,我的 headers 将从 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”宏吗?
有更好的方法吗?
简短的回答是:否在 Visual C++ 运行时的实现中依赖内部预处理器定义是不安全的,从技术上讲,所有以单个 [ 开头的编译器符号=11=] 保留供实现使用。
比如_NOEXCEPT
在Visual Studio2015和2017年内部使用过,但是截至VS 2017(15.8更新),这个宏已经不存在了; headers直接使用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
我想创建 headers,它使用来自标准 C++ 的 'optional'。 但是,我的 headers 将从 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”宏吗? 有更好的方法吗?
简短的回答是:否在 Visual C++ 运行时的实现中依赖内部预处理器定义是不安全的,从技术上讲,所有以单个 [ 开头的编译器符号=11=] 保留供实现使用。
比如_NOEXCEPT
在Visual Studio2015和2017年内部使用过,但是截至VS 2017(15.8更新),这个宏已经不存在了; headers直接使用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