2009-06-29 5 views
2

次のコードは、イベントの送出に使用するものの単純化されたバージョンです。テンプレートファンクタの引数にstatic_cast < T * >があり、ファンクタに渡された引数がstatic_castにキャストされるものが であることを確認する重要な点は です。evil static_castsを管理するパターンがあります

struct AbstractArg { 
    virtual ~AbstractArg() { } 
}; 

struct AbstractFunctor { 
    virtual void operator()(AbstractArg*) const = 0; 
    virtual ~AbstractFunctor() { } 
}; 


namespace evil { 

template<typename ArgT> 
struct CastingFunctor : AbstractFunctor { 
    void operator()(AbstractArg* aarg) const 
    { 
    ArgT* arg = static_cast<ArgT*>(arg); // Danger! 
    // ... do stuff with it 
    } 
}; 

} // namespace evil 


class TypeidManager 
{ 
public: 
    typedef std::map<std::string, AbstractFunctor*> map_type; 

    void dispatch(AbstractArg* arg) const 
    { 
    map_type::const_iterator it = typeid_map.find(std::string(typeid(*arg).name())); 
    if (it != typeid_map.end()) 
    { 
     AbstractFunctor* pFunctor = it->second; 
     (*pFunctor)(arg); 
    } 
    }; 

    template<typename ArgT> 
    void register_func(void (*fun_ptr)(ArgT*)) 
    { 
    typeid_map.insert(std::make_pair(std::string(typeid(ArgT).name()), 
            new evil::CastingFunctor<ArgT>)); 
    } 

private: 
    map_type typeid_map; 
}; 

このパターンの名前はありますか?

ありがとうございます!

+0

比較のために.name()の結果を使用しないでください。そのコンテンツについて何ら保証はありません。マップに&typeid(ArgT)の結果を格納し、2つのtypeidを比較するコンパレータを使用すること(ポインタを先に参照解除する)。 –

+0

わかりやすくするために、このコードで.name()を使用しました。実際のコードはLokiのtype_infoラッパーを使用しています。 –

答えて

3

これはアンチパターンではなく、タイプ消去でよく使用される便利なテクニックです。

+0

litbが書いたものを読むと、 "Type Erasure"はパターン/テクニックの名前だと思います。私は彼のコメントに印を付けることができないので、彼はあなたの答えに言及しています。 –

+0

:)これは良い読書のようです:http://www.artima.com/cppsource/type_erasure.html –

0

私が知っているわけではありませんが、ここでは似たようなものを使用します。

1

模様ではなく、模様ではないと思います。通常、typeid_map構造体を介してファンクタにフィードしたいものは、共通の継承階層から来て、代わりに動的多型(=仮想メソッド)を使用します。基本的には、(非常に非効率的な方法で)仮想メソッドテーブルのルックアップを再発明しました。

+0

私は主に同意します、パターンは境界線ですが、その使用があります。その主な利点は、クライアントクラスにインターフェイス/継承を強制しないことです。 – bltxd

+1

これは良いパターンです。 boost :: function、boost :: any、その他のロードなどのlibで使用されます。もう一つの答えが言うように、これはタイプ消去と呼ばれています。悪いことは、それを悪用することです。あなたが訪問者パターンを乱用することができるように、このパターンを悪用することができます。ここに任意の容器についての記事があります:http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf –

+0

ありがとう、litb –

関連する問題