Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将重载函数传递给运算符?_C++_Templates_C++11_Operator Overloading_Function Pointers - Fatal编程技术网

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;
}