我如何参考std :: sin(const valarray< double>&)? [英] How do I refer to 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< double>&)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!