2

まず、シングルトンの遅延初期化のパターンがとても気に入っています。次のように使用して、さまざまな値の型を持つさまざまな種類のデータを取得します (例は単純化されています)。

class A
{
    template<typename T>
    const T& getData() const
    {
        static T data;
        return data;
    }
}

data変数がクラスのどのインスタンスにも接続されておらず、プログラムが終了するまで存在することがわかっています。

しかし、私が今欲しいのは、クラス A の各インスタンスが非静的な方法で変数を保持する.getData<bool>()必要があることですクラス定義。

それは可能ですか?私はそれを実装するというアイデアを思いつきませんでした。

私は次のようなコンテナで何かを考えました:

template<A*, typename T>
class DataContainer
{
    T data;
}

これにより、コードを次のように拡張できます。

class A
{
    template<typename T>
    const T& getData() const
    {
        static DataContainer<this, T> container;
        return container.data;
    }
}

しかし、それはコンパイルされません。

あなたの誰かがそれを実装する方法を知っていますか?

4

1 に答える 1

2

Boost.any を使用した 1 つのアイデアを次に示します。

#include <typeinfo>
#include <type_index>
#include <unordered_map>
#include <boost/any.hpp>

struct ThingGetter
{
    template <typename T>
    T & get()
    {
        auto key = std::type_index(typeid(T));
        auto it = things.find(key);

        if (it == things.end())
        {
            it = things.emplace(key, boost::any(T())).first;
        }

        return boost::any_cast<T&>(*it);
    }

    std::unordered_map<std::type_index, boost::any> things;
};

この単純なバージョンでは、各型を値で初期化できると想定し、要求された型のエントリが存在しない場合は、値で初期化された値を作成します。別の実装では、null の可能性があるポインタを返し、別の挿入インターフェイスを持つことができます。

使用法:

ThingGetter mythings;

mythings.get<bool>() = true;
mythings.get<double>() = 1.5;
return mythings.get<int>();
于 2015-04-12T17:34:55.230 に答える