引数

2012-02-02 4 views
3

は、私は次のテンプレート機能を持って言うように複雑な関数を渡すと、バリアント:引数

template <class T> 
void apply(const vector<complex<T> >& in, vector<T>& out, T (*f)(complex<T>)) 
{ 
    out.resize(in.size()); 
    for(size_t i = 0; i < in.size(); ++i) out[i] = f(in[i]); 
} 

あなたは私だけ複雑なデータのベクトルに関数を適用したい、見て、ベクターに結果を格納することができます実データの私はこれが機能の全リストのために良いはずです:abs、norm、real、imag、等

私の問題は、どのように関数を渡すのですか?

apply(in, out, abs)の変形をabsに別のテンプレートを提供してみました。私はかなり複雑なすべてのテンプレートの機能から問題が生じると確信していますが、正しく渡す方法がわかりません。助けてくれてありがとう。

答えて

4

std::abs<complex>)は、constへの参照としてstd::complex<T>パラメータを受け取ります。あなたの関数ポインタは、不一致の原因となる値だけを示します。次のコードはうまくコンパイル:

#include <vector> 
#include <complex> 

template <class T> 
void apply(const std::vector<std::complex<T> >& in, std::vector<T>& out, 
      T (*f)(std::complex<T> const&)) 
{ 
    out.resize(in.size()); 
    for(size_t i = 0; i < in.size(); ++i) 
     out[i] = f(in[i]); 
} 

int main(){ 
    std::vector<std::complex<float> > vcomp; 
    std::vector<float> vf; 
    apply(vcomp, vf, &std::abs<float>); 
} 

Live example on Ideone.

良いアイデアは、しかし、単にテンプレートパラメータとして関数の型を取るために、次のようになります。

template <class T, class F> 
void apply(const std::vector<std::complex<T> >& in, std::vector<T>& out, F f) 
{ 
    out.resize(in.size()); 
    for(size_t i = 0; i < in.size(); ++i) 
     out[i] = f(in[i]); 
} 

Live example on Ideone.

いずれの場合でも、関数がテンプレートの場合は、キャストを使用してコールサイトで明確にする必要があります。がオーバーロードされています(私は<complex>関数から手を離せませんが、わかりません)。

// taking std::abs as an example. It's not actually templated *and* overloaded 
typedef float (*func_ptr)(std::complex<float> const&); 
apply(vcomp, vf, (func_ptr)&std::abs<float>); 
+0

'pow'は*テンプレートと*オーバーロードされますが、常に2つの引数をとります。 –

+0

私は 'abs'やその他の複雑な関数が' const& 'を取るこ​​とに気づいていませんでした。それは一貫して文書化されていないようです。すべての作品は今、ありがとう。 – steveo225

0

私の知る限り、あなたも何をしたいstd::transformで行うことができるよう、applyを発明する必要はありません。

#include <vector> 
#include <complex> 
#include <algorithm> 

int main(){ 
    std::vector<std::complex<double> > complex_vec(10); 
    std::vector<double> double_vec; 
    double_vec.resize(complex_vec.size()); 
    std::transform(complex_vec.begin(), complex_vec.end(), 
       double_vec.begin(), std::abs<double>); 
    return 0; 
} 
+0

私は実現しましたが、私の実際の機能にはもっと多くのものがあり、提供されたのは問題を説明するための小さな例に過ぎませんでした。 – steveo225

+0

@ steveo225:あなたの 'apply'関数がもっと機能するか、' apply'で使う予定の関数がもっと多くなるのですか? 2番目の場合は、まだ 'transform'を使うことができます。 –

+0

私の 'apply'関数は、より多くのことを行います、単純な例が必要です – steveo225