5

ヘッダーのみのプロジェクトがあります。その中にクラスがあります。その内部(または実際には他の場所)に定数データ(列挙値を文字列に、またはその逆)にしたいです。この問題は、私が予想していたよりもはるかに難しいようです。

typedef boost::bimap<MyEnum,std::string> Data;

私が試したがうまくいかなかったこと:

  1. static Data const s_data = _initData();:エラーは次のようになります:only static const integral data members can be initialized within a class

  2. static Data const * const s_pData = _initData();_initData()関数には静的ローカル変数(最初の呼び出しでいっぱいになりました)があり、そのアドレスを返しました。上記と同じ理由で動作しませんでした。

私が試し、作業したこと、しかし私はそれを醜いと思います:

class Ugly {
public:
    static MyEnum lookupByName(std::string s)
    {
        MyEnum ret;
        lookup(ret,s,true);
        return ret;
    }
    static String lookupByEnum(MyEnum e)
    {
        std::string ret;
        lookup(e,ret,false);
        return ret;
    }
    static void lookup(MyEnum &e, std::string &s, bool etos)
    {
        static Data s_data = _fill();
        if(etos)
            s = /* ... */;
        else
            e = /* ... */;
    }
    static Data _fill(){ /* ... */ };
};

アイデア?

4

1 に答える 1

8

シンプルなのは

static T& global_t()
{ static T z = initializer; return z; }

global_t()T値が必要な場合に使用できます。

:riokiのコメントへの回答として、関数inlineをグローバルレベルまたは名前空間レベルであるかのように指定する必要があります(リンカーに対する「複数のインスタンス」の問題を回避するため)。

関数がテンプレートであるか、クラスメンバー関数である場合(インライン定義がデフォルトである場合)、inlineキーワードは必要ありません。

インスタンス化を異なるOSモジュール(読み取り:DLL)間で共有する必要がある場合、static Triokiは完全に正しいですが、その時点では、ヘッダーのみのライブラリは意味がありません。


C ++ 17以降、inline指定子は変数にも使用できます。

したがって、C ++ 17以降では、次のように書くことができます。

inline T global_object = initializer;

関数の静的メンバーにインラインを使用して、次のようなインライン初期化を提供することもできます。

class Class
{
    static inline Type static_object_name = initializer;
};
于 2013-03-08T12:52:42.130 に答える