2012-02-02 104 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>)将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'的模板*和*超载,但是它总是需要两个参数。 – 2012-02-02 13:50:18

+0

我不知道'abs'和其他复杂函数需要'const&'。这似乎没有一致记录。现在所有的作品,谢谢。 – steveo225 2012-02-02 19:15:45

0

据我所知,你甚至都不需要去创造​​apply,你想要什么可以std::transform做到:

#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 2012-02-02 14:25:15

+0

@ steveo225:你的意思是你的'apply'函数做了更多的事情,或者你打算使用'apply'函数做更多的事情?如果第二个,很可能你仍然可以使用'transform'。 – 2012-02-02 16:48:43

+0

我的'apply'函数做得比示例更多,只需要一个简单的例子 – steveo225 2012-02-02 19:13:49