简体   繁体   English

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

[英]Is '_HAS_CXX17' marco usable in custom project headers to enable C++17 language set features?

I want to create headers which use 'optional' from standard C++. 我想创建使用标准C ++中的“可选”的标头。 However, My headers will be referred from Visual Studio 2015 as well as Visual Studio 2017 projects. 但是,我的标题将从Visual Studio 2015以及Visual Studio 2017项目中引用。

I would like to have something, such that for Visual Studio 2017 ( with C++ 17 lang feature set) , std::optional is used and with Visual Studio 2015, boost::optional gets used. 我希望有一些东西,例如,对于Visual Studio 2017(使用C ++ 17 lang功能集),使用std :: optional,使用Visual Studio 2015,使用boost :: optional。

I am thinking of something like this: 我在考虑这样的事情:

#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

Is it okay to use '_HAS_CXX17' macro this way? 可以这样使用'_HAS_CXX17'宏吗? Is there a better way of doing this? 有没有更好的方法呢?

The short answer is: No It's not safe to rely on internal preprocessor defines in the implementation of the Visual C++ Runtime, and technically all compiler symbols that begin with a single _ are reserved for use by the implementation. 简短的回答是: 在Visual C ++运行时的实现中依赖内部预处理器定义是不安全的,并且技术上所有以单个_开头的编译器符号都保留供实现使用。

For example, _NOEXCEPT has been used internally in Visual Studio 2015 and 2017, but as of VS 2017 (15.8 update), this macro no longer exists; 例如, _NOEXCEPT已在Visual Studio 2015和2017内部使用,但从VS 2017(15.8更新)开始,此宏不再存在; the headers just use noexcept directly. 标题只是直接使用noexcept

The recommendation to use __has_include is good, but isn't supported prior to VS 2017 (15.3 update). 使用__has_include的建议很好,但在VS 2017(15.3更新)之前不受支持。

The other challenge is that __cplusplus doesn't indicate you are using /std:c++17 unless you are using VS 2017 (15.7 update) with the new /Zc:__cplusplus switch which is off by default. 另一个挑战是__cplusplus并不表示你正在使用/std:c++17除非你使用VS 2017(15.7更新)和新的/Zc:__cplusplus开关默认关闭。

Probably the safest way to do this across a range of VS versions would be: 在一系列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

See Visual C++ Language Conformance 请参阅Visual C ++语言一致性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM