【发布时间】:2012-07-28 02:24:26
【问题描述】:
我需要将函数传递给操作员。任何具有正确 arg 类型的一元函数。返回类型可以是任何东西。因为这是库代码,所以我无法将其包装或将f 强制转换为特定的重载(operator* 之外)。函数将operator* 第一个参数作为它自己的参数。下面的人工示例编译并返回正确的结果。但它硬编码了int 返回类型——以使这个示例编译。
#include <tuple>
#include <iostream>
using namespace std;
template<typename T>
int operator* (T x, int& (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
cout << tpl * get<0>;
}
是否可以让operator* 接受具有任意返回类型的f?
更新 - GCC 错误? 代码:
#include <tuple>
template<typename T, typename U>
U operator* (T x, U& (*f)(T&) ) {
return (*f)(x);
};
int main() {
std::tuple<int,int> tpl(42,43);
return tpl * std::get<0,int,int>;
}
使用 gcc462 和 453 可以正确编译和运行,但使用 gcc471 和 480 时会被拒绝。因此可能是 GCC 回归错误。我已经提交了错误报告: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111
编辑 我已将示例更改为使用元组作为 arg - 在前面的示例中可以简单地推断出返回类型。
EDIT2
很多人无法理解需要什么,所以我将call 函数更改为operator* 以使示例更真实。
【问题讨论】:
-
My question 可能对您有所帮助。它允许我通过
someVar = wrap (funcName, arg1, arg2, arg3);调用包装的变体。它也处理void返回类型。 -
一般来说,类型推导和重载在 C++ 中有些矛盾。你已经走到了极限——更多的概括,然后没有足够的信息来确定要选择什么重载。
-
编辑完全改变了问题,您应该为此创建一个不同的问题,顺便说一句,它无法解决,因为
get<0>不是一个函数,std::get是一个可变参数模板,从中在使用过程中可以推断除第一个参数之外的所有参数,但是,如果不向函数提供参数,您必须手动提供所有模板参数,此时您不需要推断,因为您可以从手动的参数中获取它传递给get模板... -
@DavidRodríguez - 不,
get<0>就足够了。示例 BTW 编译并运行并返回正确的值。get<0>参数在call签名中指定。在前面的例子中,f也是模板。
标签: c++ templates c++11 operator-overloading function-pointers