2013-02-27 12 views
5

私は、テンプレートトリッキーとブースト:: anyの両方を含むライブラリを作成しています。私がわいせつネストされたシリーズに頼ることができboost :: anyとtemplates

template <typename A1, typename A2, typename A3, typename A4> 
void somefunc (A1 a1, A2 a2, A3 a3, A4 a4); 

:私は、私は基本的に、この持っているような状況に遭遇しました:

boost::any a1, a2, a3, a4; 

を...と私はこのようになります関数を呼び出す必要がありますif文の10個の異なる型を扱っていると仮定すると、それは10,000個のif文です! Boostプリプロセッサはここで助けになるかもしれませんが、これはまだ恐ろしい解決策です。

このような狂気に頼ることなく、boost :: anyの内容でテンプレート関数を呼び出すより良い方法はありますか?私が知る限りでは、そうではありません。

+0

ユーザーのみを:: any'インスタンスは実行時に正確な値を得ることができます(ハードコーディングされた型を提供しています)。コンパイル時に*型が削除されたため、その関数を 'boost :: any'に含まれる値で呼び出すことはできません。あなたが解決しようとしているより大きな問題は何ですか? 'boost :: any'はかなり低レベルのものです。 – GManNickG

+3

すべての 'any'オブジェクトを1つのオブジェクトにして、一度にそれらをすべて設定するときは、正しい' somefunc'インスタンスへのポインタも安全です(例えば、 '&somefunc ')。 – Xeo

+0

@GManNickG私が解決しようとしているより大きな問題は、一方ではLuaバインディングの自動生成と、任意の非同期関数からの結果を保持するboost :: anyです。この状況ではどちらも他のものに置き換えることはできません。 – Xtapolapocetl

答えて

10

すべてのanyオブジェクトを同時に設定できる場合は、関数ポインタの型をその場でハードコードすることができます。それをすべて別のオブジェクトに入れておいてください。これはtype-erasureをダブルテイク、そしてまた(boost::anyが内部でどのように動作するかのような)仮想関数を介して実装することができ、基本的ですが、私は、このバージョンより好き: `後押しの

// note that this can easily be adapted to boost::tuple and variadic templates 
struct any_container{ 
    template<class T1, class T3, class T3> 
    any_container(T1 const& a1, T2 const& a2, T3 const& a3) 
    : _ichi(a1), _ni(a2), _san(a3), _somefunc(&somefunc<T1, T2, T3>) {} 

    void call(){ _somefunc(_ichi, _ni, _san); } 

private: 
    boost::any _ichi, _ni, _san; 
    // adjust to your need 
    typedef void (*func_type)(boost::any&, boost::any&, boost::any&); 
    func_type _somefunc; 

    template<class T1, class T2, class T3> 
    void somefunc(boost::any& a1, boost::any& a2, boost::any& a3){ 
    // access any objects with 'boost::any_cast<TN>(aN)' 
    } 
}; 
+0

華麗な、ありがとう。 – Xtapolapocetl

+0

+1、特に_ichi、_ni、および_san変数の場合。 –