How to transfer an overloaded function to an operator?

I need to pass the function to the operator. Any unary function that has the correct arg type. The return type can be any. Since this is library code, I cannot wrap it or distinguish f from a specific overload (outside of operator* ). The function takes operator* 1st arg as its own argument. The artificial example below compiles and returns the correct results. But it has a hardcoded int return type - for compiling this example.

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

Is it possible to make operator* to accept f with an arbitrary return type?

UPDATE - GCC bug? The code:

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

It compiles and works correctly with gcc462 and 453, but is rejected with gcc471 and 480. Thus, a GCC regression error is possible. I sent an error report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111

EDIT I changed the example of using tuple as arg - in the previous example it is possible to output the return type trivially.

EDIT2 Many people could not figure out what was needed, so I changed the call function to operator* to make the example more real.

+6
source share
3 answers

As an answer to your updated question:

as discussed in @ DavidRodríguez, get<0> not enough, and not syntactically correct &get<0> . You need &get<0,int,int> . Following your example, this will be:

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

In normal use, std::get<>() int,int is automatically output. But in your situation you need to provide it, since there are no parameters. One way is to use the get template custom function:

 #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; } 
+2
source

Yes, if that is what you mean:

 template<typename T, typename F> auto call (T x, F f) -> decltype(f(x)) { return (f)(x); } 

There are actually many ways to do this.

+4
source

You should be able to do this:

 template<typename T,typename U> U call (T x, U (*f)(T) ) { return (*f)(x); }; 
+2
source

Source: https://habr.com/ru/post/921545/


All Articles