コンパイラがC ++ 11の特定の機能をサポートしているかどうかをコンパイル時に検出する方法はありますか?たとえば、次のようなもの:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
コンパイラがC ++ 11の特定の機能をサポートしているかどうかをコンパイル時に検出する方法はありますか?たとえば、次のようなもの:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
回答:
__cplusplus
C ++コンパイラがサポートされているC ++標準のバージョンに設定する必要があるという名前の定数があります。
#if __cplusplus <= 199711L
#error This library needs at least a C++11 compliant compiler
#endif
Visual Studio 2010 SP1では199711Lに設定されていますが、ベンダーが(部分的な)コンパイラーレベルのサポートを持っているだけで、C ++ 11がすべて変更された標準のC ++ライブラリを持っている場合、ベンダーがそれを大きくするかどうかはわかりません。
したがって、別の回答で言及されているBoostの定義は、たとえば、C ++ 11スレッドや標準の他の特定の部分がサポートされているかどうかを判断する唯一の健全な方法のままです。
__cplusplus
に設定します201103L
。これは、2011年の規格に完全に準拠していることを示しています。部分的な準拠やコンパイラの拡張については説明しません。__cplusplus
がに設定されている場合は201103L
、コンパイラーが完全に準拠しているか、ユーザーに依存しています。そうでない場合、それがサポートする機能を実際に判別することはできません。
-std=c++11
オプションが指定されている場合(これも)でこれを設定します-std=gnu++11
。完全な機能ではありませんが、これを行います(4.8を使用すると、かなり接近します)。注-コンパイラがサポートするものと標準ライブラリで利用できるものの間にはギャップがあります。現在、4.7.xと4.8.xの両方に正規表現のサポートがありませんが、これはライブラリーであり、コンパイラー機能ではありません。
__cplusplus
する199711L
C ++ 11のために
__cplusplus
するコンパイラ199711L
は、準拠するC ++ 11コンパイラではありません。彼らはおそらくそれらを正しく動作させるためのオプションを持っています。
C ++ 11標準(§iso.16.8)で述べられているように:
名前__cplusplusは、C ++変換単位のコンパイル時に値201103Lに定義されます。
そのマクロの値を使用して、コンパイラがC ++ 11に準拠しているかどうかを確認できます。
さて、コンパイラがC ++ 11機能のサブセットをすべてサポートしているかどうかを確認する標準的な方法を探しているのであれば、標準的な移植可能な方法はないと思います。詳細については、コンパイラのドキュメントまたはstdライブラリヘッダーファイルを確認してください。
私はこれが非常に古い質問であることを知っていますが、この質問はしばしば見られる可能性があり、答えは少し時代遅れです。
C ++ 14標準の新しいコンパイラには、C ++ 11機能を含む機能をチェックする標準的な方法があります。包括的なページはhttps://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendationsにあります
要約すると、各機能には、で確認できる標準マクロが定義されています#ifdef
。たとえば、ユーザー定義のリテラルをチェックするには、次のように使用できます
#ifdef __cpp_user_defined_literals
__has_include()
マクロです。
あなたはこれを使うことができます:
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
cout << "C++11 is supported";
#else
cout << "C++11 is not supported";
#endif
C ++ 11の場合、Visual Studioを除くほとんどのコンパイラーは__cplusplus
マクロを201103L
に設定しますが、Visual Studioのどのバージョンでも、199711L
C ++ 11より前の他のコンパイラーで使用される値を設定します。このコードは、_cplusplus
マクロ201103L
をVisual Studioを除くすべてのコンパイラーと比較し、コンパイラーがVisual Studioの場合、Visual Studioのバージョンが2015以降であるかどうかを確認します。スタジオ2015、_MSC_VER
マクロには値があります。この回答を1900
参照してください)。
g++ -std=c++98
GCC 4.8で、それは間違って印刷しますC++11 is supported
。
Boost.Configを使用せず、C ++ 11をサポートするコンパイラをテストする必要がある場合は、定数の値をチェックする__cplusplus
ことで実行できます。ただし、コンパイラーはC ++ 11標準の一般的な機能のほとんどをサポートしている可能性がありますが、仕様全体をサポートしているわけではありません。C ++ 11仕様にまだ100%準拠していない特定のVisual Studioコンパイラーのサポートを有効にする場合は、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に配置するバグのテストに使用されます。
template <typename... Test> struct compiler_must_support_variadic_templates;
。構文エラーは問題をすぐに明らかにします。(余談ですが、適切なエラーメッセージの方がはるかに優れています。)