web-dev-qa-db-ja.com

C ++ 11xサポートを検出するためのプリプロセッサディレクティブはありますか?

可能な限りC++ 11x拡張機能を使用したいコードがありますが、これがサポートされていない場合はフォールバックが必要です。現在、GCCのOSXバージョンとVisualCコンパイラはC++ 11xをほとんどまたはまったくサポートしていないため、以下を使用します。

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

そして、これは機能しますが、特にMacPortsのgccコンパイラはc ++ 11xをサポートしているため、本当に正しいことではありません。

ありますか #define C11X_SUPPORTEDタイプマクロ?おそらく、GCCだけが持っているものでしょうか?

49
Kenneth

__cplusplusは、C++ 11以前のコンパイラでは199711L、C++ 11をサポートしているコンパイラでは201103Lとして定義する必要があります。これが実際に大いに役立つかどうかは別の質問です。ほとんどのコンパイラはそこにあるだけなので、たとえあなたが興味のある機能をサポートしていても、201103Lとして定義すべきではありません。嘘をつくコンパイラ:199711Lとして定義し、たとえばテンプレートのexportをサポートしないコンパイラ。ただし、機能テストによる標準機能はありません。

最も単純な解決策は、すべてのコンパイラがサポートすることを確認できるまで、特定の新機能を使用しないことです。とにかくフォールバックコードを記述してサポートする必要があります。 2つのバージョンを維持する理由。この規則の1つの例外は、パフォーマンスに影響する新機能である可能性があります。コンパイラが移動セマンティクスをサポートしているかどうかです。そのような場合、コンパイラー依存のインクルードファイルをお勧めします。これは、コンパイラーのドキュメントと個人的なテストに基づいて自分で作成します。コンパイラが特定の機能をサポートしていることを文書化するからといって、そのサポートにバグがないとは限りません。ターゲットコンパイラごとにディレクトリを作成し、そこにこのファイルを配置して、メイクファイルまたはプロジェクトファイルで適切な-Iまたは/Iオプションを指定します。

そして、あなたのテストは次のようなものでなければなりません:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

コンパイラー、バージョン、その他何でもではありません。

52
James Kanze

__cplusplusマクロの値を確認できます。 C++ 11の場合、199711Lより大きい。

のようなもの

#if __cplusplus > 199711L

#endif
26
Luchian Grigore

Boost.Config ライブラリは 粒状プリプロセッサマクロ を提供します。これを使用して、特定のC++ 11機能の存在に基づいて条件付きでコンパイルできます。

(コンパイラの場合、C++ 11のサポートは、すべてまたは何も命題である必要はありません。たとえば、Microsoft チェリーがどのC++ 11の機能を選択したか に基づいてVisual Studio 2012に含める方法を検討してください顧客に最も利益をもたらすと考えられています。)

7
Edward Brey