5

テンプレートのトリックとboost::anyの両方を大量に含むライブラリを書いています。私は本質的にこれを持っている状況に遭遇しました:

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

...そして、次のような関数を呼び出す必要があります。

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

わいせつにネストされた一連の if ステートメントに頼ることもできますが、10 個の異なる型を処理していると仮定すると、10,000 個の if ステートメントになります! ここでは Boost プリプロセッサが役立ちますが、これは依然として恐ろしい解決策です。

この種の狂気に頼らずに、boost::any の内容でテンプレート化された関数を呼び出すより良い方法はありますか? 私が知る限り、ありません。

4

1 に答える 1

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)'
  }
};
于 2013-02-27T01:26:08.023 に答える