Say I want a C++ function to perform 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);
}
functions that fit OP might be like:
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 would the signature for function look like? If the operator functions are non-templated I can do it, but I get confused with this extra complexity.
template <class OP> void function(OP op)
{
// call with int
op(1, 2);
// or with double
op(1.2, 2.3);
// call with explicit template argument
op.template operator()<int>(1, 2);
op.template operator()<string>("one", "two");
}
struct Add
{
template <class T> T operator ()(T a, T b)
{
return a + b;
}
};
function(Add());
// or call with C++14 lambda
function([](auto a, auto b) { return a + b; });
Template functions cannot be passed as template arguments. You have to manually deduce template arguments for this function before you pass it to another template function. For example, you have 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 simply write
int a = callFunc(1, 2, sum);
You have to write
int a = callFunc(1, 2, sum<int>);
To be able to pass sum without writing int, you have to write a functor - struct or class with operator() that will call your template function. Then you can pass this functor as 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With