Pass pointer-to-template-function as an argument to a function?

Let's say I want a C ++ function to do arithmetic on two inputs, treating them as a given type:

pseudo:

function(var X,var Y,function OP) { if(something) return OP<int>(X,Y); else if(something else) return OP<double>(X,Y); else return OP<string>(X,Y); } 

which correspond to OP may be as follows:

 template <class T> add(var X,var Y) { return (T)X + (T)Y; //X, Y are of a type with overloaded operators } 

So the question is, what will the signature for the function look like? If the operator functions are not templated, I can do it, but I'm confused about this extra complexity.

+6
c ++ operator-overloading templates
source share
6 answers

I'm a little confused ... why type differentiation in your pseudocode?

C ++ templates allow full type inference to templates:

 template <typename T, typename F> T function(T x, T y, F op) { return op(x, y); } 

Here, F is suitable for something (especially a function) that can be called with the function call syntax () and takes exactly two arguments of type T (or is implicitly converted to it).

+5
source share

Template functions cannot be passed as template arguments. You must manually infer the template arguments for this function before passing it to another template function. For example, you have a function

 T sum(T a, T b) { return a + b; } 

You want to pass it to callFunc:

 template<typename F, typename T> T callFunc(T a, T b, F f) { return f(a, b); } 

You can't just write

 int a = callFunc(1, 2, sum); 

You need to write

 int a = callFunc(1, 2, sum<int>); 

To be able to pass the sum without an int record, you need to write functor - struct or class with operator (), which will call your template function. Then you can pass this functor as a template argument. Here is an example.

 template<class T> T sum(T a, T b) { return a + b; } template<class T> struct Summator { T operator()(T a, T b) { return sum<T>(a, b); } }; template<template<typename> class TFunctor, class T> T doSomething(T a, T b) { return TFunctor<T>()(a, b); //Equivalent to this: //TFunctor<T> functor; //return functor(a, b); } int main() { int n1 = 1; int n2 = 2; int n3 = doSomething<Summator>(n1, n2); //n3 == 3 return 0; } 
+5
source share

Are you looking for this?

 template<class T> T add(TX, TY) { return X + Y; } 

Or are you looking for something that causes something like add?

 template<class T, class F> T Apply(T x, T y, F f) { return f( x, y ); } 

Called through:

 int x = Apply( 2, 4, add<int> ); 
+4
source share

I think you are looking for a Strategy Template .

+1
source share

I am using lambdas for this.

 auto add = [](const auto& lhs, const auto& rhs) { static_assert(std::is_arithmetic<typename std::decay<decltype(lhs)>::type>::value, "Needs to be arithmetic."); static_assert(std::is_arithmetic<typename std::decay<decltype(rhs)>::type>::value, "Needs to be arithmetic."); return lhs + rhs; }; template<typename LHS, typename RHS, typename FUNC , typename OUT = typename std::result_of<FUNC(LHS, RHS)>::type> constexpr OUT do_arithmetic(LHS lhs, RHS rhs, FUNC func) { return func(lhs, rhs); } constexpr auto t = do_arithmetic(40, 2, add); static_assert(t == 42, "Wrong answer!"); static_assert(std::is_same<std::decay<decltype(t)>::type, int>::value, "Should be int."); 
+1
source share

I'm not sure what this var thing is in your question. This, of course, is not a valid C ++ keyword, so I assume it is a type similar to boost:any . In addition, the function does not have a result type. I added another var , whatever that is. Your solution might look like this:

 template< template<typename> class Func > var function(var X, var Y, Func OP) { if(something) return OP<int>(X,Y); else if(something else) return OP<double>(X,Y); else return OP<string>(X,Y); } 

A funny template argument is the template itself, so its name is "template template argument". You pass the name of the template, not the instance. That is, you pass std::plus , not std::plus<int> :

 return function( a, b, std::plus ); 
0
source share

All Articles