0

変数テンプレートを使用して独自の適用関数を作成しようとしています。ここに私が持っているコードがあります:

    template<typename...>
    struct types{
    };

    template<typename T, typename... Args>
    struct Func{
        template<typename F, typanem... Types>
        T call(F f, std::tuple<Types...>& params, Args... args){
            return _call(f, params, types<Types...>{}, args...);
        }
        template<typename F, typename Tuple, typename Head, typename... Tail, typename... Args>
        T _call(F f, Tuple& t, types<Head, Tail...>, Args&&... args){
            _call(f, t, types<Tail...>{}, std::forward<Args>(args)..., std::get<sizeof...(Arg)>(t).DrawSample()));
        }
        T _call(F f, Tuple& t, types<>, Args... vs){ 
            return f(vs...)
        }
    };

上記のコードを問題なくコンパイルして実行できます。ここで、関数 call(...) を遅延して呼び出したいと思います。つまり、計算に必要なすべてのパラメーターを渡すことで、最初に関数を作成できます。

    int getMax(float f1, float f2, float f3){
      if(f1 >= f2 && f1 >= f3){
          return 1;
      }
      if(f2 >= f1 && f2 >= f3){
          return 2;
      }
      if(f3 >= f1 && f3 >= f2){
          return 3;
      }
    }
    Func<int> func;
    //Gaussian(mu, sd) is an object which can generate random values based on Gaussian 
    //distribution described with mu(mean) and sd(standard deviation).
    Gaussian *g1 = Gaussian(0.3, 0.2);
    Gaussian *g2 = Gaussian(0.2, 0.3);
    Gaussian *g3 = Gaussian(0.3, 0.3);
    func.setCall(getMax, std::make_tuple(*g1, *g2, *g3);
    cout<<func.DrawSample();

関数を構築した後、func.DrawSample() のクエリを作成するたびに、getMax() 関数の結果を遅延取得したいと考えています。内部では、おそらく DrawSample() が call(...) を呼び出します。ただし、後で関数呼び出しに必要なすべてを格納することを目的とする setCall(...) を作成するために、上記のコードを変更する方法はありますか?

私の質問がまだ不明な場合はお知らせください。助けてくれてどうもありがとう!

4

3 に答える 3

0

DanielKO から提供された提案により、最終的に特定のシナリオの解決策を思いつきました。これが私のコンパイル済みコードの最終バージョンです。

    template<class Func, class... Args>
    int applyDrawSample(Func func, Args&&... args){
        return func((*args).DrawSample()...);
    }
    template<class Func, class... Args>
    auto bind_helper(Func func, Args&&... args) ->decltype(bind(applyDrawSample<Func, Args...>,  
        func, args...))
    {
        return bind(applyDrawSample<Func, Args...>, func, args...);
    }

    template<typename T>
    struct UncertainFunc{
        template<typename F, typename... Args>
        void setFunc(F f, Args... args){
            function = bind_helper(f, args...);
        }
        T DrawSample(){
            return function();
        }
        std::function<T()> function;
    };

    UncertainFunc<int> ufunc;
    ufunc.setFunc(getMax, &(Gaussian(0.3, 0.2), &Gaussian(0.2, 0.3), &Gaussian(0.2, 0.2));
    ufunc.DrawSample();

特に、何らかの理由で bind_helper(...) 関数をクラス定義に入れることができないようです (おそらく auto タイプ?)。

于 2013-10-24T16:07:05.713 に答える
0

およびラムダを使用std::function<int()>します。

std::function<int()> func;
func = [=]()->int {
  return getMax( Guassian(0.3,0.2), Guassian(0.2,0.3), Guassian(0.3,0.3) );
};
std::cout << func();

インターフェースが本当に本当に必要な場合は、 を に保存し、std::function<T()>classそれsetCallに割り当てるだけです。

しかし、実際には、オブジェクトは、問題を解決するために呼び出すことができる匿名型ですintstd::functionクラスの型には関数シグネチャが含まれていないため、とにかく型消去を行う必要があるため、おそらくこれ以上効率的ではありません。

于 2013-10-23T21:07:17.913 に答える