C++ 如何引用std::sin(const valarray<;double>;)?

C++ 如何引用std::sin(const valarray<;double>;)?,c++,function-pointers,functional-programming,C++,Function Pointers,Functional Programming,我遇到一些函数指针代码的问题: double (*fp)(double) = sin; valarray<double> (*fp)(const valarray<double> &) = sin; double(*fp)(double)=sin; valarray(*fp)(const valarray&)=sin; 第一个编译,第二个给出: error: no matches converting function 'sin' to type 'class

我遇到一些函数指针代码的问题:

double (*fp)(double) = sin;
valarray<double> (*fp)(const valarray<double> &) = sin;
double(*fp)(double)=sin;
valarray(*fp)(const valarray&)=sin;
第一个编译,第二个给出:

error: no matches converting function 'sin' to type 'class std::valarray<double> (*)(const class std::valarray<double>&)'
错误:将函数“sin”转换为类型“class std::valarray(*)(const class std::valarray&)”时没有匹配项

您在标题中谈到了
std::sin
,但随后分配了
::sin

valarray<double> (*fp)(const valarray<double> &) = std::sin;
valarray(*fp)(const valarray&)=std::sin;
这应该行得通。请注意,您应该限定
sin
的所有用法,尽管大多数实现都会将名称注入全局命名空间,即使您包含
(这是非标准行为)

编辑:不幸的是,你运气不好。该标准规定了关于sin(valarray const&)的以下内容(26.3.3.3)

此函数应返回一个类型为T的值或可以明确定义的值 转换为T型

gcc执行的优化由标准授予。上述代码不保证有效。

26 3.1/3

任何返回valarray的函数都可以返回另一种类型的对象, 假设valarray的所有常量成员函数也适用于此类型

其目的是允许使用模板表达式优化结果(即,每次计算时在整个数组上循环一次,直接分配给结果数组,而不是构建临时数组)

可以优化为

for (i = 0; i < N; ++i)
   z[i] = sin(x[i] + y[i]);
(i=0;i z[i]=sin(x[i]+y[i]);
这将使用GCC扩展名的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。看起来GCC的
valarray
使用表达式模板来延迟窦房结的计算。但这将使
sin
模板的返回类型不完全是
valarray
,而是某种奇怪的复杂类型

#include <valarray>

template<typename T> struct id { typedef T type; };
int main() {
  using std::valarray;
  using std::sin;

  id<__typeof__(sin(valarray<double>()))>::type (*fp)(const valarray<double> &) = sin;
}
如果要立即获取地址,可以编写
work
,这样它会再次返回
fp

template<typename T>
T addy(T fp, id<T>) { return fp; }

你说得对,在GCC上它确实失败了。不过我得说这是一只虫子。该标准明确定义了
模板valarray sin(const valarray&)
当然可以转换为
valarray(*)(const-valarray&)
。我同意。看起来像是GCC的疯狂:(我同时对你像MacGyver一样将条件运算符转换为问题的解决方案的能力印象深刻,并对这样做的必要性感到震惊。)@robert,如果你不理解某些部分,请随时提问。我会尽力给他们解释的。另外,请务必阅读eric nieblers关于他使用
操作符的解释:
第一个变体也应该适用于所有已经支持C++11
decltype
的编译器(在将
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#include <valarray>

using std::valarray;

template<typename T> struct id {
  typedef T type;
};

struct ded_ty {
  template<typename T>
  operator id<T>() { return id<T>(); }
};

template<typename E, typename T>
id<T(*)(valarray<E> const&)> genFTy(T t) { 
  return id<T(*)(valarray<E> const&)>(); 
}

template<typename T>
void work(T fp, id<T>) {
  // T is the function pointer type, fp points
  // to the math function.
}

int main() {
  work(std::sin, 1 ? ded_ty() : genFTy<double>(std::sin(valarray<double>())));
}
template<typename T>
T addy(T fp, id<T>) { return fp; }
#define DEDUCE(FN,Y) (1 ? ded_ty() : genFTy<Y>(FN(std::valarray<Y>())))
std::transform(v1.begin(), v1.end(), v1.begin(),
  addy(std::sin, DEDUCE(std::sin, double)));
std::transform(v2.begin(), v2.end(), v2.begin(),
  addy(std::cos, DEDUCE(std::cos, double)));