我需要将一个函数传递给一个操作符。任何具有正确arg类型的一元函数。返回类型可以是任何东西。因为这是库代码,所以我无法将其包装或将f
转换为特定的重载(operator*
之外)。函数将operator*
1st arg作为自己的参数。下面的人工示例编译并返回正确的结果。但它已经硬编码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*
以使示例更加真实。
答案 0 :(得分:4)
是的,如果这是你的意思:
template<typename T, typename F>
auto call (T x, F f) -> decltype(f(x)) {
return (f)(x);
}
实际上有很多方法可以做到这一点。
答案 1 :(得分:2)
你应该可以这样做:
template<typename T,typename U>
U call (T x, U (*f)(T) ) {
return (*f)(x);
};
答案 2 :(得分:2)
作为对最新问题的回答:
正如@DavidRodríguez所讨论的那样,get<0>
是不够的,也不是合成正确的&get<0>
。你需要的是&get<0,int,int>
。按照你的例子,它将是:
#include <tuple>
using namespace std;
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
call(tpl, &get<0,int,int>);
return 0;
}
在正常使用std::get<>()
期间,int,int
部分会自动推断。但在你的情况下,你需要提供它,因为没有参数。一种解决方法是自定义get
模板功能:
#include <tuple>
using namespace std;
template <size_t I, typename T>
auto myGet(T& tpl) -> decltype(get<I>(tpl))
{
return get<I>(tpl);
}
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
auto get0 = &myGet<0, decltype(tpl)>;
call(tpl, get0);
// call(tpl, &myGet<0, decltype(tpl)>); // all in one line, do not work
return 0;
}