3

私の C++ プロジェクト (autotools を使用) には、メンバー関数begin()とメンバー関数を持つクラスがあり、C++11 がサポートされている場合に限り、オプションでandend()を含めたいと考えています。cbegin()cend()

Autoconf アーカイブの M4 ファイルを使用して、C++11 のサポートをテストします。サポートされている場合は HAVE_CXX11 を定義するマクロで、サポートされていない場合は定義しません。

私が望むことを行うCの方法は次のとおりです。

#ifdef HAVE_CXX11
    const_iterator cbegin () const;
    const_iterator cend () const;
#endif

しかし、私は C++ の方法でいくつかのことをしたいと考えています。この場合std::enable_if、オプションcbeginで とを許可するために使用できますcend。このような:

#ifdef HAVE_CXX11
#define MY_HAVE_CXX11 true
#else
#define MY_HAVE_CXX11 false

constexpr bool have_cxx11 ()
{
    return MY_HAVE_CXX11;
}

/* Now use have_cxx11() with std::enable_if */

これは単一の特定のマクロでは問題なく機能しますが、特定のマクロに対して自動化したい場合はどうすればよいでしょうか? 言い換えれば、私が欲しいのは、特定のマクロが定義されているかどうかを示すブール値を取得することです。

2 つのオプションが表示されます。

  1. マクロごとに特定の機能を持つ
  2. 単一の機能を持つ

1 の例:

autoconf がその変数 HAVE_CXX11 を定義する場合、HAVE_CXX11 autoconf 変数 (マクロ定数ではない) が 0 または 1 に定義されているかどうかに応じて、true または false を返すように have_cxx11() も定義します。

2 の例:

macro_is_defined()これは、ブール値を返す関数にすることができます。たとえば、C++11 プロジェクトをビルドするmacro_is_defined(HAVE_CXX11)と返されます。true

これらのアイデアを純粋な C++ で実装する方法を見つけようとしましたが、見つかりませんでした。コードの 1 行をプリプロセッサ ディレクティブのブロックに展開する必要がありましたが、これは IIRC では不可能です。私は何をすべきか?そして、私が試したように C++ の方法で物事を行うのは良い考えですか、それとも多すぎますか?

編集:

autoheader は#undef、最終的にコメントアウトされるものも含め、すべてのマクロに対して を作成します。したがって、config.h をスキャンしてマクロごとに constexpr 関数を生成するスクリプトを作成できます。問題は、ビルド プロセスのどこに挿入し、どのように呼び出すかです。

4

3 に答える 3