如何将重载函数传递给运算符?

Leo*_*sky 6 c++ templates function-pointers operator-overloading c++11

我需要将一个函数传递给一个操作符.任何具有正确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>;
}
Run Code Online (Sandbox Code Playgroud)

是否有可能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>;
}  
Run Code Online (Sandbox Code Playgroud)

用gcc462和453正确编译和运行,但是gcc471和480拒绝.所以它可能是GCC回归错误.我已经提交了错误报告:http: //gcc.gnu.org/bugzilla/show_bug.cgi?id = 54111

编辑 我已经改变了使用元组作为arg的例子 - 在前面的例子中可以简单地推断出返回类型.

编辑2 很多人无法理解需要什么,所以我改变了call功能operator*,使例子更真实.

use*_*2k5 2

作为您更新问题的答案:

\n\n

正如 @DavidRodr\xc3\xadguez 所讨论的,get<0>这还不够,语法上也不正确&get<0>。你需要的是&get<0,int,int>. 按照你的例子,它将是:

\n\n
#include <tuple>\nusing namespace std;\n\ntemplate<typename T, typename U>\nU call (T x, U (*f)(T&) ) {\n      return (*f)(x);\n};\n\nint main() {\n    tuple<int,int>  tpl(42,43);\n    call(tpl, &get<0,int,int>);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

正常使用时std::get<>()int,int会自动推算该部分。但在您的情况下,您需要提供它,因为没有参数。一种解决方法是自定义get模板函数:

\n\n
#include <tuple>\nusing namespace std;\n\ntemplate <size_t I, typename T>\nauto myGet(T& tpl) -> decltype(get<I>(tpl))\n{\n    return get<I>(tpl);\n}\n\ntemplate<typename T, typename U>\nU call (T x, U (*f)(T&) ) {\n      return (*f)(x);\n};\n\n\nint main() {\n    tuple<int,int>  tpl(42,43);\n    auto get0 = &myGet<0, decltype(tpl)>;\n    call(tpl, get0);\n\n//  call(tpl, &myGet<0, decltype(tpl)>); // all in one line, do not work\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n