Czy istnieje sposób na wykrycie w czasie kompilacji, czy kompilator obsługuje niektóre funkcje C ++ 11? Na przykład coś takiego:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
template <typename... Test> struct compiler_must_support_variadic_templates;
. Błąd składni szybko ujawniłby problem. (Tak na marginesie, właściwy komunikat o błędzie jest znacznie lepszy.)Odpowiedzi:
Istnieje stała o nazwie,
__cplusplus
którą kompilatory C ++ powinny ustawić na wersję obsługiwanego standardu C ++. Zobacz toJest ustawiony na 199711L w Visual Studio 2010 SP1, ale nie wiem, czy dostawcy będą tak śmiali, aby go już zwiększyć, jeśli mają tylko (częściowe) wsparcie na poziomie kompilatora w porównaniu ze standardową biblioteką C ++ ze wszystkimi zmianami w C ++ 11 .
Tak więc definicje Boost wspomniane w innej odpowiedzi pozostają jedynym rozsądnym sposobem ustalenia, czy istnieje na przykład wsparcie dla wątków C ++ 11 i innych określonych części standardu.
źródło
__cplusplus
to201103L
. To potwierdza pełną zgodność ze standardem 2011; nie mówi o częściowej zgodności ani o rozszerzeniach kompilatora. Jeśli__cplusplus
jest ustawiona na201103L
, to albo kompilator w pełni się zgadza, albo cię okłamuje. Jeśli tak nie jest, nie możesz tak naprawdę powiedzieć, które funkcje obsługuje.-std=c++11
podano opcję (może również-std=gnu++11
). Robią to, mimo że nie są do końca kompletne (4.8 znacznie przybliża nas). Uwaga - istnieje luka między tym, co obsługuje kompilator, a tym, co jest dostępne w bibliotece standardowej. W obu wersjach 4.7.xi 4.8.x brakuje obecnie obsługi wyrażeń regularnych - ale jest to biblioteka, a nie funkcja kompilatora.__cplusplus
to199711L
dla języka C ++ 11.__cplusplus
na,199711L
nie jest zgodnym kompilatorem C ++ 11. Prawdopodobnie mają opcje, aby zachowywać się poprawnie.Jak stwierdzono w standardzie C ++ 11 (§iso.16.8):
Dzięki wartości tego makra można sprawdzić, czy kompilator jest zgodny z C ++ 11.
Jeśli szukasz standardowego sposobu sprawdzenia, czy kompilator obsługuje jakikolwiek podzbiór funkcji C ++ 11, myślę, że nie ma standardowego, przenośnego sposobu; możesz sprawdzić dokumentację kompilatorów lub pliki nagłówkowe bibliotek std, aby uzyskać więcej informacji.
źródło
Wiem, że to bardzo stare pytanie, ale często można je spotkać, a odpowiedzi są nieco nieaktualne.
Nowsze kompilatory ze standardem C ++ 14 mają standardowy sposób sprawdzania funkcji, w tym funkcji C ++ 11. Obszerna strona znajduje się pod adresem https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
Podsumowując, każda funkcja ma zdefiniowane standardowe makro, które można sprawdzić
#ifdef
. Na przykład, aby sprawdzić literały zdefiniowane przez użytkownika, możesz użyćźródło
__has_include()
makro.Sprawdź obsługę C ++ 14 i innych. Testowanie na GCC 5.2.1.
źródło
Możesz użyć tego:
W przypadku języka C ++ 11 większość kompilatorów, z wyjątkiem programu Visual Studio, ustawia
__cplusplus
makro na201103L
, ale każda wersja programu Visual Studio ustawia go199711L
jako wartość używaną przez inne kompilatory przed C ++ 11. Ten kod porównuje_cplusplus
makro ze201103L
wszystkimi kompilatorami z wyjątkiem programu Visual Studio, a jeśli kompilatorem jest program Visual Studio, sprawdza, czy wersja programu Visual Studio jest nowsza niż 2015, pierwsza wersja programu Visual Studio, która w pełni obsługuje C ++ 11 (dla programu Visual Studio 2015,_MSC_VER
makro ma wartość1900
, zobacz odpowiedź ).źródło
g++ -std=c++98
przypadku GCC 4.8 drukuje nieprawidłowoC++11 is supported
.Jeśli nie chcesz używać Boost.Config i potrzebujesz przetestować kompilatory obsługujące C ++ 11, wystarczy sprawdzić wartość stałej
__cplusplus
. Jednak kompilator może obsługiwać większość popularnych funkcji standardu C ++ 11, ale nie obsługuje wszystkich specyfikacji. Jeśli chcesz włączyć obsługę określonych kompilatorów programu Visual Studio, które nie są jeszcze w 100% zgodne ze specyfikacjami C ++ 11, użyj następującego fragmentu kodu, który umożliwia kompilację w programie Visual Studio 2013:Pełną listę wersji kompilatora dla programu Visual Studio podano w artykule Jak wykryć, czy kompiluję kod w programie Visual Studio 2008
źródło
W tradycyjnym świecie Linuksa / Uniksa autoconf jest tradycyjnie używany do testowania obecności bibliotek i funkcji kompilatora oraz błędów umieszczania ich w pliku config.h, którego używasz w swoich plikach w razie potrzeby.
źródło
Kiedy sprawdzasz dostępność biblioteki C ++ 11 (nie funkcję języka), na przykład
<array>
nagłówek, możesz#if __has_include(<array>)
.Czasami sprawdzenie
#if __cplusplus >= 201103L
powie Ci, że używasz C ++ 11, ale inne ustawienia, takie jak ustawienie standardowej wersji biblioteki w Xcode, mogą nadal nie mieć dostępnych nowych bibliotek (większość z nich jest dostępna pod różnymi nazwami, tj.<tr1/array>
)źródło