Подтвердить что ты не робот

Существует ли препроцессорная директива для обнаружения поддержки С++ 11x?

Если у вас есть код, в котором я хотел бы использовать расширения С++ 11x как можно больше, но иметь резервную копию, если это не поддерживается. В настоящее время версия GCC для OSX и компилятор VisualC практически не поддерживают С++ 11x, поэтому я использую:

#if (defined(__APPLE__) || (defined(_WIN32)))
   ...fallback code without C++11x ...
#else
   ... code using C++11x ...
#endif

И это работает, но на самом деле это не совсем правильно, тем более, что gcc-компилятор в MacPorts поддерживает С++ 11x.

Существует ли макрос типа #define C11X_SUPPORTED? Возможно, что-то только GCC имеет?

4b9b3361

Ответ 1

__cplusplus должен быть определен как 199711L в компиляторах pre-С++ 11, 201103L в тех, кто поддерживает С++ 11. На практике это другой вопрос: большинство компиляторов только на полпути, поэтому не следует определять его как 201103L, даже если они поддерживают функции, которые вас интересуют. И это не неслыханно для компилятора для lie: компилятор, который определяет его как 199711L и не поддерживает export для шаблонов, например. Но функциональная проверка не существует.

Самое простое решение - просто не использовать какую-либо конкретную новую функцию, пока не убедитесь, что все ее компиляторы поддерживают ее. Вы все равно должны писать и поддерживать резервный код; зачем поддерживать две версии. Единственным исключением из этого правила могут быть новые функции, которые влияют на производительность: поддерживает ли компилятор семантику переноса или нет. В таких случаях я бы предложил включить зависимый от компилятора файл, который вы пишете на основе документации компилятора и личных тестов; просто потому, что компилятор может документировать, что он поддерживает определенную функцию, не означает, что его поддержка не является ошибкой. Просто создайте каталог для каждого целевого компилятора, поместите туда этот файл и укажите подходящую опцию -I или /I в файле makefile или файла проекта.

И ваши тесты должны быть чем-то вроде:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

а не только на компилятор, версию или что-то еще.

Ответ 2

Вы можете проверить значение макроса __cplusplus. Для С++ 11 это больше, чем 199711L.

Так что-то вроде

#if __cplusplus > 199711L

#endif

Ответ 3

Библиотека Boost.Config предоставляет макросы гранулированных препроцессоров, которые можно использовать для условной компиляции на основе присутствия данной функции С++ 11.

(Для компилятора поддержка С++ 11 не обязательно должна быть предложением "все или ничего". Например, рассмотрим, как Microsoft вишня выбрала, какие функции С++ 11 включить в Visual Studio 2012 на основе того, что, по их мнению, принесет наибольшую пользу своим клиентам.)