Можно ли использовать марку ‘_HAS_CXX17’ в пользовательских заголовках проекта для включения функций набора языков C ++ 17?

Я хочу создать заголовки, которые используют «опционально» из стандартного C ++.
Тем не менее, мои заголовки будут ссылаться из Visual Studio 2015, а также проектов Visual Studio 2017.

Я хотел бы иметь что-то, например, для Visual Studio 2017 (с набором функций языка C ++ 17 lang), используется std :: extra, а в Visual Studio 2015 используется boost :: option.

Я думаю о чем-то вроде этого:

#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» таким образом?
Есть ли лучший способ сделать это?

3

Решение

Краткий ответ: нет Не безопасно полагаться на внутренние определения препроцессора в реализации среды выполнения 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 ++

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]