Как проверить поддержку С++ 11?

Есть ли способ обнаружить во время компиляции, если компилятор поддерживает некоторые функции С++ 11? Например, что-то вроде этого:

#ifndef VARIADIC_TEMPLATES_SUPPORTED

#error "Your compiler doesn't support variadic templates.  :("

#else

template <typename... DatatypeList>
class Tuple
{
    // ...
}

#endif

Ответы

Ответ 2

Существует константа с именем __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 и других конкретных частей стандарта.

Ответ 3

Как указано в стандарте С++ 11 (§iso.16.8):

Имя __ cplusplus определяется значением 201103L, когда компиляция единицы перевода С++.

Со значением этого макроса вы можете проверить, соответствует ли компилятор С++ 11.

Теперь, если вы ищете стандартный способ проверить, поддерживает ли компилятор какое-либо подмножество функций С++ 11, я думаю, что нет стандартного портативного способа; вы можете проверить документацию компиляторов или файлы заголовков std, чтобы получить дополнительную информацию.

Ответ 4

Я знаю, что это очень старый вопрос, но этот вопрос часто можно увидеть, и ответы немного устарели.

Новые компиляторы со стандартом С++ 14 имеют стандартный способ проверки функций, включая возможности С++ 11. Полная страница находится на https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations

Таким образом, каждая функция имеет стандартный макрос, который можно проверить с помощью #ifdef. Например, чтобы проверить определенные пользователем литералы, вы можете использовать

#ifdef __cpp_user_defined_literals

Ответ 5

Я просто написал небольшой набор тестов, чтобы проверить, какие функции С++ 11 поддерживаются конкретным компилятором. Тем не менее, это, конечно, "предварительная компиляция".

https://github.com/sloede/cxx11tests

Ответ 6

Для проверки поддержки С++ 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;
}

Ответ 7

Если вы не хотите использовать 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

Ответ 8

В традиционном мире Linux/Unix, autoconf традиционно используется для проверки наличия библиотек и функций компилятора и ошибок, помещая их в config.h, которые вы используете в своих файлах по мере необходимости.

Ответ 9

Вы можете использовать это:

#if __cplusplus >= 201103L || (__cplusplus < 200000 && __cplusplus > 199711L)
    cout << "C++11 is supported";
#else
    cout << "C++11 is not supported";
#endif

Для С++ 11 некоторые компиляторы устанавливают макрос __cplusplus в 201103L, а другие устанавливают его в 199711L. Это решение совместимо с обоими этими случаями.