Templated function pointer with arguments as template parameter - c++

I can't get my code to compile. I want to be able to declare a function that takes another function (or a class with operator() defined, or lambda expression) as parameter, and this function has template arguments as well. Here's an example of what I want to do:
template <class T, T F>
T execF(T a, T b)
{
return F(a, b);
}
template <class T>
T add(T a, T b)
{
return a + b;
}
int main()
{
std::cout << execF<int, add>(3,4) << std::endl;
}
Is it possible to do something like this in C++14?

It should be:
template <class T, T F(T, T)>
T execF(T a, T b)
{
return F(a, b);
}
If you want to omit all template parameters, I suggest to stick with Some Programmer Dude's comment and accept the function as a function parameter:
template <typename T>
T execF(T a, T b, T f(T, T))
{
return f(a, b);
}
template <typename T>
T add(T a, T b) { return a + b; }
int main(int , char **)
{
auto x = execF(41.8f, 0.2f, add); //all params deduced in both functions
std::cout << x << std::endl;
x = execF(27, 15, add); //idem
std::cout << x << std::endl;
return 0;
}

Related

C++ function call wrapper with function as template argument

I'm trying to create a generic wrapper function that takes a function as a template argument and takes the same arguments as that function as its arguments. For example:
template <typename F, F func>
/* return type of F */ wrapper(Ts... Args /* not sure how to get Ts*/)
{
// do stuff
auto ret = F(std::forward<Ts>(args)...);
// do some other stuff
return ret;
}
The solution needs to be castable to a function pointer with the same type as func so that I can pass it to a C api. In other words, the solution needs to be a function and not a function object. Most importantly, I need to be able to do work in the wrapper function.
If the inline comments aren't clear, I'd like to be able to do something like the following:
struct c_api_interface {
int (*func_a)(int, int);
int (*func_b)(char, char, char);
};
int foo(int a, int b)
{
return a + b;
}
int bar(char a, char b, char c)
{
return a + b * c;
}
c_api_interface my_interface;
my_interface.func_a = wrapper<foo>;
my_interface.func_b = wrapper<bar>;
I looked for related posts and found these, but none of them are quite what I'm trying to do. Most of these posts concern function objects. Is what I'm trying to do even possible?
Function passed as template argument
Function wrapper via (function object) class (variadic) template
How does wrapping a function pointer and function object work in generic code?
How do I get the argument types of a function pointer in a variadic template class?
Generic functor for functions with any argument list
C++ Functors - and their uses
In response to the first 2 responses, I edited the question to make it clear that I need to be able to do work in the wrapper function (i.e. modify some global state before and after the call to the wrapped function)
template<class F, F f> struct wrapper_impl;
template<class R, class... Args, R(*f)(Args...)>
struct wrapper_impl<R(*)(Args...), f> {
static R wrap(Args... args) {
// stuff
return f(args...);
}
};
template<class F, F f>
constexpr auto wrapper = wrapper_impl<F, f>::wrap;
Use as wrapper<decltype(&foo), foo>.
#include <utility>
#include <iostream>
struct c_api_interface { int (*func_a)(int, int); int (*func_b)(char, char, char); };
int foo(int a, int b) { return a + b; }
int bar(char a, char b, char c) { return a + b * c; }
template<typename Fn, Fn fn, typename... Args>
typename std::result_of<Fn(Args...)>::type
wrapper(Args... args) {
std::cout << "and ....it's a wrap ";
return fn(std::forward<Args>(args)...);
}
#define WRAPIT(FUNC) wrapper<decltype(&FUNC), &FUNC>
int main() {
c_api_interface my_interface;
my_interface.func_a = WRAPIT(foo);
my_interface.func_b = WRAPIT(bar);
std:: cout << my_interface.func_a(1,1) << std::endl;
std:: cout << my_interface.func_b('a','b', 1) << std::endl;
return 0;
}
see http://rextester.com/ZZD18334
you may try something like that (Ugly, but works)
#include <iostream>
#include <functional>
struct wrapper_ctx
{
wrapper_ctx ()
{
std::cout << "Before" << std::endl;
}
~wrapper_ctx ()
{
std::cout << "after" << std::endl;
}
};
template <typename F, typename... Args>
auto executor (F&& f, Args&&... args) -> typename std::result_of<F(Args...)>::type
{
wrapper_ctx ctx;
return std::forward<F>(f)( std::forward<Args>(args)...);
}
template <typename F>
class wrapper_helper;
template<typename Ret, typename... Args>
class wrapper_helper <std::function<Ret(Args...)>>
{
std::function<Ret(Args...)> m_f;
public:
wrapper_helper( std::function<Ret(Args...)> f )
: m_f(f) {}
Ret operator()(Args... args) const
{
return executor (m_f, args...);
}
};
template <typename T>
wrapper_helper<T> wrapper (T f)
{
return wrapper_helper <T>(f);
}
int sum(int x, int y)
{
return x + y;
}
int main (int argc, char* argv [])
{
std::function<int(int, int)> f = sum;
auto w = wrapper (f);
std::cout << "Executing the wrapper" << std::endl;
int z = w(3, 4);
std::cout << "z = " << z << std::endl;
}
you probably need something like
template <typename F>
class Wrapper {
public:
Wrapper(F *func) : function(func) {}
operator F* () { return function; }
F *function;
};
Which you can use like void (*funcPtr)(int) = Wrapper<void(int)>(&someFunction);
I think that will be the concise way to do what you want:
template <typename F>
F* wrapper(F* pFunc)
{
return pFunc;
}
and use it like this:
my_interface.func_a = wrapper(foo);
my_interface.func_a(1, 3);
You may try this
template <class R, class... Args>
struct wrap
{
using funct_type = R(*)(Args...);
funct_type func;
wrap(funct_type f): func(f) {};
R operator()(Args&&... args)
{
//before code block
std::cout << "before calling\n";
R ret=func(std::forward<Args>(args)...);
//after code block
std::cout << "After calling\n";
}
};
use like this for example:
int somefunc(double &f, int x);
auto wrapped_somefunc=wrap{somefunc};
double f=1.0;
int x = 2;
auto result=wrapped_somefunc(f,x);
This one is for c++17 and newer uses auto template parameters:
template <auto func, class... Args>
auto wrap_func(Args... args)
{
std::cout << "before calling wrapped func\n";
auto ret = func(args...);
std::cout << "after calling wrapped func\n";
return ret;
}
use for example:
int some_func(int a, int b);
auto ret = wrap_func<some_func>(2, 3);

C++ using function template in class template

template <int C> class MyClass;
...
template <int C>
double trans(MyClass<C> &a)
{
//return some double
}
//this is supposed to be function template
template <int C>
double func(MyClass<2> &a)
{
//return some double
}
template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
MyClass<C-1> ret;
return ret;
}
template <int C>
double otherFunc(MyClass<C> &a)
{
double result;
if(C == SOME_CONSTANT)
result = func(a);
else
result = trans(func(a));
}
What my problem is I want to check template argument C in parameter otherFunc call function template func (return double) instead of member function of class template func(return MyClass). But somehow compiler attempts to func that returns MyClass in
if(C == SOME_CONSTANT)
result = func(a);
this part so I got compiler error (because double = MyClass is not viable). How should I fix this problem?
Hard to elaborate in a comment, so I'll post an answer. To recap what I said in comments:
you can't have an if/else in otherFunc that won't be legal to compile for a specific MyClass instantiation,
you can use the same template specialisation approach to create an alternative otherFunc definition to handle MyClass<2>s.
Sample code:
#include <iostream>
template <int C>
class MyClass
{ };
template <int C>
double trans(const MyClass<C> &a)
{
return C + 700;
}
template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
MyClass<C-1> ret;
return ret;
}
double func(MyClass<2>& a)
{
return 200.0;
}
template <int C>
double otherFunc(MyClass<C> &a)
{
return trans(func<C>(a));
}
template <>
double otherFunc<2>(MyClass<2>& a)
{
return func(a);
}
int main()
{
MyClass<2> a;
std::cout << otherFunc(a) << '\n';
MyClass<4> b;
std::cout << otherFunc(b) << '\n';
}
Output:
200
703
I guess the reason is that:
if(C == SOME_CONSTANT)
result = func(a);
else
result = trans(func(a));
is checked in the runtime, while template specializations and type check is done during compilation. Those 2 functions:
template <int C>
double func(MyClass<2> &a)
{
//return some double
}
template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
MyClass<C-1> ret;
return ret;
}
have almost the same signatures - the only difference is that for C==2 is used the one returning double, otherwise used the one returning MyClass<2>. So what you get is:
// for C==2
if(C == SOME_CONSTANT)
result = func<2>(a); // returns double - just like you wanted
else
result = trans<2>(func<2>(a)); // pass double into trans<?>(MyClass<?>), so the parameter cannot be resolved unless you specified some implicit constructor/explicit conversion operator
// for e.g. C==3
if(C == SOME_CONSTANT)
result = func<3>(a); // returns MyClass<2> while result is double
else
result = trans<2>(func<3>(a)); // pass MyClass<2> into trans<?>(MyClass<>) - like you wanted
so basically your code have invalid type for specializations in either first or second case. You can do something like this instead:
template <>
MyClass<2> func<2>(MyClass<2> &a)
{
return a;
}
template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
return MyClass<C-1>;
}
to keep templates type consistent, and then:
if(C == SOME_CONSTANT)
result = trans(a);
else
result = trans(func(a));
It's just an example how to handle it. Things should be easier if you avoid messing with different return typed for different template specializations.

How to pass template function to another function

I have below template function, and now I want to add a function testfun whose parameter will be each template function and its parameters. but I do not know how to define and implement testfun. Any comments is appreciated. Thanks!
template<typename T>
T hoo(T x)
{
return x;
}
template<typename T, typename... Args>
T hoo(T first, Args... rest)
{
return first + hoo(rest...);
}
int a = 1, b = 2, c = 3;
int tsum = hoo<int>(a, b);
std::cout << tsum << std::endl;
std::string sa = "a", sb = "b";
std::string tssum = hoo<std::string>(sa, sb);
std::cout << tssum << std::endl;
testfun(hoo, a, b); //testfun looks like this
testfun(hoo, sa, sb); //testfun looks like this
//[Update] Add more request
testfun(hoo, a, b, c); //testfun also support this
I assume you want that:
template <typename T, typename... Args>
T testfun(T (&f) (T, Args...), T tail, Args... queue)
{
return f(tail, queue...); // or any other implementation
}

Calling template function pointer with variable argument number

I want to write a function that calls another function with its arguments. See how I want that it work:
int sum(int a, int b) { return a + b }
int succ(int a) { return a + 1 }
int size(char* str) { return strlen(str) }
int call(???) { ??? }
int main() {
cout << call(sum, 1, 2) << endl;
cout << call(succ, 41) << endl;
cout << call(size, "teste") << endl;
}
Expected output:
3
42
5
How can I write the call function (assuming that the return value is always the same)? The only way that I can think is this:
template<typename T> int call(T func, int a, int b) { return func(a, b) }
template<typename T> int call(T func, int a) { return func(a) }
template<typename T> int call(T func, char* a) { return func(a) }
Is there any way to solve this repetition with templates, va_list or anything else?
Intention:
It's for drawing geometry pictures, parsing a function with the parametric equation to be drawed. Example:
Vector2i circle(float t, float radius) {
return Vector2i(cos(t * 2*PI) * radius, sin(t * 2*PI) * radius);
}
// ...
draw(circle, 10);
The function circle will be called many times inside draw with diferents ts (between 0.0 and 1.0). The others arguments of draw is sent directly to the funcions, 10 will be radius. (Vector2i is a custom class).
C++0x variadic templates:
template<typename Func, typename... Args>
auto call(Func func, Args&&... args)
-> typename std::result_of<Func(Args...)>::type
{
return func(std::forward<Args>(args)...);
}
Add another template variable:
template<typename T, typename U>
int call(T func, U a) { return func(a) }
template<typename T, typename U, typename V>
int call(T func, U a, V b) { return func(a,b) }
How about a simple #define for current C++ solution:
#define call(FUNC, ...) FUNC(__VA_ARGS__)
Here is the demo. I would advise to use a better name then a generic name like call as you are using #define.

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

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 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;
}
Are you looking for this?
template<class T> T add(T X, T Y)
{
return X + Y;
}
Or are you looking for something that calls something like add?
template<class T, class F>
T Apply(T x, T y, F f)
{
return f( x, y );
}
Called via:
int x = Apply( 2, 4, add<int> );
I'm a bit confused … why the type differentiation in your pseudo-code?
C++ templates allow full type deduction on templates:
template <typename T, typename F>
T function(T x, T y, F op) {
return op(x, y);
}
Here, F fits anything (especially functions) that may be called with the () function call syntax and accepting exactly two arguments of type T (or implicitly convertible to it).
I use 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.");
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; });
I think you're looking for the Strategy Pattern.
I'm not sure what this var thing in your question means. It's certainly not a valid C++ keyword, so I assume it's a type akin to boost:any. Also, the function is missing a result type. I added another var, whatever that might be. The your solution could 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);
}
The funny template argument is a template itself, hence its name "template template argument". You pass in the name of a template, not an instance. That is, you pass std::plus, not std::plus<int>:
return function( a, b, std::plus );