“_HAS_CXX17”marco是否可用于自定义项目标题以启用C ++ 17语言集功能?

问题描述 投票:3回答:1

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

我希望有一些东西,例如,对于Visual Studio 2017(使用C ++ 17 lang功能集),使用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个回答
1
投票

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

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

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

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

在一系列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

© www.soinside.com 2019 - 2024. All rights reserved.