2

type_indexテンプレート引数として渡された各タイプのポインターにマップされたキーのマップを含むクラスを作成しようとしています。これにより、クラスの宣言で依存する一連の型を指定できます。

私は少し調査を行いましたが、型ではなく引数をアンパックする方法しか見つけられないようです。私はこの主題に慣れていないので、用語の説明や関連テキストへの参照をいただければ幸いです。

template <typename T>
T* SomeFakeFactoryGetter() { return new T(); }

template <class... Injected>
class UtilityProvider
{
public:
    template <class U>
    U* GetUtility()
    {
        std::type_index idx = std::type_index(typeid(U));
        assert(_injectedClasses.find(idx) != _injectedClasses.end());
        return reinterpret_cast<U*>(_injectedClasses[idx]);
    }

    // **
    // How would I *unpack* all types for use as indices into my map?
    // ( I realise this function is not what I want.)
    template <Injected... C>
    void Unpack()
    {
        _injectedClasses[std::type_index(typeid(C))] = SomeFakeFactoryGetter<C>();
    }

private:
    typedef std::unordered_map<std::type_index, void*> InjectedMap;
    InjectedMap _injectedClasses;
};

class Bar{ public: void A() { printf("Hello bar"); } };
class Baz{ public: void B() { printf("Hello baz"); } };
class Nope {};

class Foo : public UtilityProvider<Bar, Baz>
{
public:
    Foo()
    {
        GetUtility<Bar>()->A();
        GetUtility<Nope>(); // Fail. User must specify which utilities this class     will use.
    }
};
4

2 に答える 2

1

別のアプローチ:

template <typename ... C> struct Unpacker;

template <typename Tail, typename ... Queue>
struct Unpacker<Tail, Queue...>
{
    void operator () (InjectedMap& injectedClasses) const
    {
        _injectedClasses[std::type_index(typeid(Tail))] = SomeFakeFactoryGetter<Tail>();
        Unpacker<Queue...>()(injectedClasses);
    }
};

template <>
struct Unpacker<>
{
    void operator () (InjectedMap& injectedClasses) const {}
};
于 2013-11-07T15:54:25.497 に答える
1

この状況で私が行ったことは、これらの式を展開するためのダミー関数を作成することですが、それは非常に恐ろしいものに見えます:

    template <int ... Dummies>
    void dummy(int&& ...){}

    template <class ... C>
    void Unpack()
    {
       dummy(((_injectedClasses[std::type_index(typeid(C))] = 
                 SomeFakeFactoryGetter<C>()), 0)...);
    }

insertあなたの場合、次のものを使用したほうがよいと思いますinitializer_list

    template <class ... C>
    void Unpack()
    {
      _injectedClasses.insert({std::make_pair(std::type_index(typeid(C)),
                                              SomeFakeFactoryGetter<C>())...});
    }

これについて直接言及しているものは見つかりませんでしたが、まだご存じない場合のために、2 つの方法には重要な違いがあると思います。 insert既存のキーと値のペアをオーバーライドしませんが、オーバーライドしますoperator[]。これは、これが重要な場合に使用する方法に影響を与える可能性があります。

于 2013-11-07T04:22:19.227 に答える