C++ 如何将重载函数传递给运算符?
我需要把一个函数传递给一个操作符。具有正确参数类型的任何一元函数。返回类型可以是任何类型。因为这是库代码,所以我不能将其包装或将C++ 如何将重载函数传递给运算符?,c++,templates,c++11,operator-overloading,function-pointers,C++,Templates,C++11,Operator Overloading,Function Pointers,我需要把一个函数传递给一个操作符。具有正确参数类型的任何一元函数。返回类型可以是任何类型。因为这是库代码,所以我不能将其包装或将f强制转换为特定重载(在运算符*之外)。函数将运算符*第一个参数作为自己的参数。下面的人工示例编译并返回正确的结果。但是它硬编码了int返回类型,以使这个示例能够编译 #include <tuple> #include <iostream> using namespace std; template<typename T> int
f
强制转换为特定重载(在运算符*
之外)。函数将运算符*
第一个参数作为自己的参数。下面的人工示例编译并返回正确的结果。但是它硬编码了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>;
}
使用gcc462和453正确编译和运行,但使用gcc471和480时被拒绝。所以有可能是GCC回归错误。我已提交错误报告:
编辑
我已经将示例更改为使用tuple作为arg-在前面的示例中可以简单地推断返回类型
EDIT2
很多人不明白需要什么,所以我将
call
函数改为operator*
,以使示例更真实 是的,如果这是你的意思:
template<typename T, typename F>
auto call (T x, F f) -> decltype(f(x)) {
return (f)(x);
}
模板
自动调用(tx,ff)->decltype(F(x)){
申报表(f)(x);
}
实际上有很多方法可以做到这一点。您应该能够做到这一点:
template<typename T,typename U>
U call (T x, U (*f)(T) ) {
return (*f)(x);
};
模板
U调用(tx,U(*f)(T)){
申报表(*f)(x);
};
作为您最新问题的答案:
正如@DavidRodríguez所讨论的,get
是不够的,语法正确的&get
。您需要的是&get
。按照您的示例,它将是:
#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;
}
也许能帮你一点忙。它允许我通过
someVar=wrap(funcName,arg1,arg2,arg3)调用包装的变体代码>。它处理的是 Value返回类型。一般来说,C++中的类型推导和重载有点不一致。你已经到了极限——更多的泛化,然后没有足够的信息来确定选择什么重载。编辑完全改变了问题,你应该为此创建一个不同的问题,顺便说一句,它无法解决,因为get
不是一个函数,std::get
是一个可变模板,在使用过程中,除了第一个参数外,其他所有参数都可以从该模板中推断出来,但是,如果不向函数提供参数,则必须手动提供所有模板参数,此时无需进行推断,正如您可以从手动传递到get
模板的参数中获得它一样…@DavidRodríguez-no,get
就足够了。示例BTW编译并运行并返回正确的值<代码>获取
参数在调用
签名中指定。在前面的示例中,f
也是模板。f可以重载。这意味着应该指定f arg type。@LeonidVolnitsky然后在将其作为参数传递之前,您必须将其转换为所需类型的函数指针。或者将其包装在lambda中,这使一切变得更加简单。我已经澄清了我的问题(请参阅重载段落)。我无法将wrap预转换为lambda。@Xeo,你能发布你所说的wrap是什么意思吗?它编译(你从我这里得到+1)。但这并不是我想要的。我的错——坏榜样。我已将其更改为使用tuple作为arg,现在您的方法将不起作用。@Xeo:No-get就足够了。不需要-可以推断。无法包装。我可以处理重载的左值/右值。@Xeo:你低估了我:)在call
签名中指定了f
参数类型。这足以提取特定的恒载。示例编译并运行。@Leonid:TIL:C++的模板参数推断比我想象的更强大。我完全忘记了模板参数推断的上下文信息。我仍然在想,为什么你不能接受一个F
模板参数?@Xeo:F
不会提取重载-->不会编译,因为不明确。如果不够,我的示例就不会编译/运行。您的第一个代码示例被拒绝gcc48@Leonid,但您的示例无法执行您想要的操作:接受任意返回类型的f
。我使用的是GCC4.6.3,第一个代码被接受。无论如何,第二个代码怎么样?我没有尝试第二个代码-正如我在问题中解释的:我不能包装或播放f
。我没有gcc463,但我试过使用gcc453和gcc471。第一个-编译并正确运行(您得到+1),第二个-拒绝。我将向gcc提交错误报告。我正在提交错误报告:我的代码是否使用gcc463正确编译和运行?@LeonidVolnitsky:正在更新的代码-gcc错误:它使用gcc 463正确编译。
#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;
}
#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;
}