0

共有ライブラリでルックアップテーブルを初期化したいのですが、これが有効な方法であるかどうかを確認したいと思います。さらに多くのライブラリで引き続き使用する場合は、これから作成します。

typedef std::map<std::string, int> NAME_LUT;
NAME_LUT g_mLUT;
namespace
{
    bool OneTimeInit() 
    {
        ::g_mLUT.insert(NAME_LUT::value_type("open",          1));
        ::g_mLUT.insert(NAME_LUT::value_type("close",         2));
        return true;
    }
    bool bInit = OneTimeInit(); // Just to make initialization happen
}

Visual Studioとgcc(Linux)の両方で正常に動作するようです。bInitgccだけが、どこにも使用されていないことを訴えます。

  1. 初期化が最適化されている(bInit使用されていない)か、言語で許可されていない(副作用のため)可能性はありますか?
  2. 確かに、1回限りの初期化を処理するための優れたクロスプラットフォームの方法のように見えますが、これが最善のアプローチであるかどうかはわかりません。
  3. OneTimeInit宣言を静的にすることは意味がありますか?(つまり、を使用するstatic bool OneTimeInit() {...})、または名前空間のみが、このコンパイルユニットに固有にするためのより良いアプローチです。
4

4 に答える 4

7

静的ストレージを使用する変数のアイデアはあまり好きではありませんが、そうする場合は、オブジェクトを初期化する関数を作成するだけで、実際にコードを簡略化できます。

typedef std::map<std::string, int> NAME_LUT;
namespace {
   NAME_LUT create_lut() {
        NAME_LUT table;
        table.insert(NAME_LUT::value_type("open",          1));
        table.insert(NAME_LUT::value_type("close",         2));
        return table;
   }
}
NAME_LUT g_mLut = create_lut();

これには、通常の初期化順序の問題がすべてあることに注意してください(異なる変換ユニット間、特にダイナミックライブラリの場合)

于 2012-05-07T16:39:46.337 に答える
3

はい、それは合法ですが、それがライブラリにあると述べているので、これを作成している翻訳がリンクされていることを確認する必要があります。

ライブラリに「未使用」のオブジェクト定義を強制的に含める方法

于 2012-05-07T16:34:40.600 に答える
1

C ++ 11初期化子リストがある場合、これはあなたにとってよりうまく機能しますか?

NAME_LUT g_mLUT = { {"open", 1}, {"close", 2}, };
于 2012-05-07T16:49:33.270 に答える
0

最適化された場合bInit(特にライブラリがdlopen編集された場合)、初期化コードは実行されません。

ユーザーが(開始後)適切な場所でライブラリにセットアップ呼び出しを行うことに問題はありますmainか?この方法でDoignを実行すると、デバッグが困難な初期化順序のバグの1つがコードに現れる可能性がなくなります。それがオプションでない場合は、静的ローカルを使用してinitを関数呼び出しに非表示にすることをお勧めします。

typedef std::map<std::string, int> NAME_LUT;
namespace
{
    bool OneTimeInit(NAME_LUT& mLUT) 
    {
        ::mLUT.insert(NAME_LUT::value_type("open",          1));
        ::mLUT.insert(NAME_LUT::value_type("close",         2));
        return true;
    }

    NAME_LUT& get_global_mLUT()
    {
        static NAME_LUT g_mLUT;
        static bool bInit = OneTimeInit(g_mLUT); // Just to make initialization happen
        return g_mLUT;
    }
}
于 2012-05-07T17:00:30.307 に答える