可能な限り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だけが持っているものでしょうか?
__cplusplus
は、C++ 11以前のコンパイラでは199711L
、C++ 11をサポートしているコンパイラでは201103L
として定義する必要があります。これが実際に大いに役立つかどうかは別の質問です。ほとんどのコンパイラはそこにあるだけなので、たとえあなたが興味のある機能をサポートしていても、201103L
として定義すべきではありません。嘘をつくコンパイラ:199711L
として定義し、たとえばテンプレートのexport
をサポートしないコンパイラ。ただし、機能テストによる標準機能はありません。
最も単純な解決策は、すべてのコンパイラがサポートすることを確認できるまで、特定の新機能を使用しないことです。とにかくフォールバックコードを記述してサポートする必要があります。 2つのバージョンを維持する理由。この規則の1つの例外は、パフォーマンスに影響する新機能である可能性があります。コンパイラが移動セマンティクスをサポートしているかどうかです。そのような場合、コンパイラー依存のインクルードファイルをお勧めします。これは、コンパイラーのドキュメントと個人的なテストに基づいて自分で作成します。コンパイラが特定の機能をサポートしていることを文書化するからといって、そのサポートにバグがないとは限りません。ターゲットコンパイラごとにディレクトリを作成し、そこにこのファイルを配置して、メイクファイルまたはプロジェクトファイルで適切な-I
または/I
オプションを指定します。
そして、あなたのテストは次のようなものでなければなりません:
#ifdef HAS_MOVE_SEMANTICS
...
#endif
コンパイラー、バージョン、その他何でもではありません。
__cplusplus
マクロの値を確認できます。 C++ 11の場合、199711L
より大きい。
のようなもの
#if __cplusplus > 199711L
#endif
Boost.Config ライブラリは 粒状プリプロセッサマクロ を提供します。これを使用して、特定のC++ 11機能の存在に基づいて条件付きでコンパイルできます。
(コンパイラの場合、C++ 11のサポートは、すべてまたは何も命題である必要はありません。たとえば、Microsoft チェリーがどのC++ 11の機能を選択したか に基づいてVisual Studio 2012に含める方法を検討してください顧客に最も利益をもたらすと考えられています。)