我如何参考std :: sin(const valarray< double>&)? [英] How do I refer to std::sin(const valarray<double> &)?

查看:160
本文介绍了我如何参考std :: sin(const valarray< double>&)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用某些 valarray 函数指针代码时遇到问题:

I'm having trouble with some valarray function pointer code:

double (*fp)(double) = sin;
valarray<double> (*fp)(const valarray<double> &) = sin;

第一次编译,第二次编译:

The first compiles, the second gives:

error: no matches converting function 'sin' to type 'class std::valarray<double> (*)(const class std::valarray<double>&)'


推荐答案

使用 __ typeof __ GCC扩展进行编译。看起来像GCC的 valarray 使用表达式模板来延迟窦的计算。但这会使 sin 模板的返回类型不完全 valarray< T> ,而是一些奇怪的复杂类型。

This compiles, using the __typeof__ GCC extension. Looks like GCC's valarray uses expression templates to delay calculation of the sinus. But that will make the return type of the sin template not exactly valarray<T>, but rather some weird complex type.

#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;
}

编辑:请参阅AProgrammer的标准报价是很好的。

See AProgrammer's standard quote for why GCC is fine doing that.

编辑:符合标准的解决方法

Standard compliant workaround

> __ typeof __ 在严格的标准符合方式是有点棘手。您将需要获取 sin 的返回类型。您可以使用条件运算符来执行此操作,如Eric Niebler 显示。它的工作原理是 sin 函数没有实际调用,只有类型检查。通过尝试将条件运算符的其他分支(实际评估的那个)转换为相同类型,我们可以生成一个虚拟参数,以便能够推导出函数指针的类型:

Doing this without __typeof__ in a strictly Standard conforming way is a bit tricky. You will need to get the return type of sin. You can use the conditional operator for this, as Eric Niebler has shown. It works by having the sin function not actually called, but only type-checked. By trying to convert the other branch (the one which is actually evaluated) of the conditional operator to that same type, we can generate a dummy parameter just to be able to deduce the type of the function pointer:

#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>())));
}

如果要立即获取地址,可以写 work ,因此它再次返回 fp

If you want to get the address right away, you can write work so it returns fp again.

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

现在,你可以写一个宏来封装条件运算符的欺骗,想要得到任何这样的数学函数的地址。

Now, you can finally write a macro to encapsulate the conditional operator trickery, and use it when you want to get the address of any such math function.

#define DEDUCE(FN,Y) (1 ? ded_ty() : genFTy<Y>(FN(std::valarray<Y>())))

地址并将其传递给一些通用函数,然后

To get the address and pass it to some generic function, the following works then

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)));

这篇关于我如何参考std :: sin(const valarray&lt; double&gt;&amp;)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆