Ответ 1
Boost.Config имеет множество макросов, которые могут быть использованы для тестирования на поддержку определенного С++ 11.
Есть ли способ обнаружить во время компиляции, если компилятор поддерживает некоторые функции С++ 11? Например, что-то вроде этого:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
Boost.Config имеет множество макросов, которые могут быть использованы для тестирования на поддержку определенного С++ 11.
Существует константа с именем __cplusplus
, которую компиляторы С++ должны установить на версию поддерживаемого стандарта С++ см. это
#if __cplusplus <= 199711L
#error This library needs at least a C++11 compliant compiler
#endif
Он установлен в 199711L в Visual Studio 2010 с пакетом обновления 1 (SP1), но я не знаю, будут ли производители смело увеличивать его, если у них есть (частичная) поддержка на уровне компилятора по сравнению со стандартной библиотекой С++ со всеми C + +11 изменений.
Значения Boost, упомянутые в другом ответе, остаются единственным разумным способом выяснить, есть ли, например, поддержка потоков С++ 11 и других конкретных частей стандарта.
Как указано в стандарте С++ 11 (§iso.16.8):
Имя __ cplusplus определяется значением 201103L, когда компиляция единицы перевода С++.
Со значением этого макроса вы можете проверить, соответствует ли компилятор С++ 11.
Теперь, если вы ищете стандартный способ проверить, поддерживает ли компилятор какое-либо подмножество функций С++ 11, я думаю, что нет стандартного портативного способа; вы можете проверить документацию компиляторов или файлы заголовков std, чтобы получить дополнительную информацию.
Я знаю, что это очень старый вопрос, но этот вопрос часто можно увидеть, и ответы немного устарели.
Новые компиляторы со стандартом С++ 14 имеют стандартный способ проверки функций, включая возможности С++ 11. Полная страница находится на https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
Таким образом, каждая функция имеет стандартный макрос, который можно проверить с помощью #ifdef
. Например, чтобы проверить определенные пользователем литералы, вы можете использовать
#ifdef __cpp_user_defined_literals
Я просто написал небольшой набор тестов, чтобы проверить, какие функции С++ 11 поддерживаются конкретным компилятором. Тем не менее, это, конечно, "предварительная компиляция".
Для проверки поддержки С++ 14 и других. Тестирование на GCC 5.2.1.
#include <iostream>
int main(){
#if __cplusplus==201402L
std::cout << "C++14" << std::endl;
#elif __cplusplus==201103L
std::cout << "C++11" << std::endl;
#else
std::cout << "C++" << std::endl;
#endif
return 0;
}
Если вы не хотите использовать Boost.Config и вам нужно протестировать компиляторы, которые поддерживают С++ 11, тогда будет проверять значение константы __cplusplus
. Однако компилятор может поддерживать большинство популярных функций стандарта С++ 11, но он не поддерживает все спецификации. Если вы хотите включить поддержку определенных компиляторов Visual Studio, которые еще не соответствуют стандарту С++ 11, то используйте следующий фрагмент кода, который позволяет компилировать в Visual Studio 2013:
#if defined(_MSC_VER)
# if _MSC_VER < 1800
# error This project needs atleast Visual Studio 2013
# endif
#elif __cplusplus <= 199711L
# error This project can only be compiled with a compiler that supports C++11
#endif
Полный список версий компилятора для Visual Studio предоставляется в Как обнаружить, если я компилирую код с помощью Visual Studio 2008
В традиционном мире Linux/Unix, autoconf традиционно используется для проверки наличия библиотек и функций компилятора и ошибок, помещая их в config.h, которые вы используете в своих файлах по мере необходимости.
Вы можете использовать это:
#if __cplusplus >= 201103L || (__cplusplus < 200000 && __cplusplus > 199711L)
cout << "C++11 is supported";
#else
cout << "C++11 is not supported";
#endif
Для С++ 11 некоторые компиляторы устанавливают макрос __cplusplus
в 201103L
, а другие устанавливают его в 199711L
. Это решение совместимо с обоими этими случаями.