C++ function call wrapper with function as template argument
#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
C++ function wrapper of a function with a template argument
typedef FT (*Implicit_function)(FT, FT, FT);
You declared that the function accepts the same type for all 3 parameters, and also returns the very same type.
Should have been typedef FT (*Implicit_function)(FT, FT, Point_vec);
Fix the signature of Implicit_function
, and your problem should be gone.
In case this is at least C++11, you should also be preferring std::function
over raw function pointer so that functions or lambdas with bindings / captures can be accepted.
FT_to_point_function_wrapper::function
should be declared const
as it is only set by initializer list in constructor. If using C++11, you may then also declare FT_to_point_function_wrapper::FT_to_point_function_wrapper
to be constexpr
.
FT_to_point_function_wrapper::operator()
should be declared to be const
as well.
C++ function call wrapper object with function as template argument
At no point in the program you specify Args and it can’t be deduced so it turns out to be an empty pack.
You can capture the arguments of the function using a partial specialization:
template<auto F> class C;
template<typename RV, typename ...Args, RV (*F)(Args...)>
class C<F>
{
...
C++ function call wrapper with class member function as template argument
The problem with member function is they need an object of the class to be called.
Supposing you can pass the object of the class, together with the pointer to the member function, to the constructor, I suppose you can write the wrapper as follows
template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...)>
{
private:
std::function<Ret(Args...)> m_f;
public:
wrapper (Cl cl, Ret(Cl::*m)(Args...))
: m_f{ [=](Args... as) mutable { return (cl.*m)(as...); } }
{ }
Ret operator() (Args... args) const
{ return m_f(args...); }
};
The following is a full compilable example of use
#include <functional>
#include <iostream>
template <typename F>
class wrapper;
template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...)>
{
private:
std::function<Ret(Args...)> m_f;
public:
wrapper (Cl cl, Ret(Cl::*m)(Args...))
: m_f{ [=](Args... as) mutable { return (cl.*m)(as...); } }
{ }
Ret operator() (Args... args) const
{ return m_f(args...); }
};
struct foo
{
long long bar (int a, long b, long long c)
{ return a+b+c; }
};
int main ()
{
foo f;
wrapper<decltype(&foo::bar)> wfb{f, &foo::bar};
std::cout << wfb(1, 2l, 3ll) << std::endl;
}
Observe that the example works for a not-const member functions.
For const member functions, you could need another wrapper
template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...) const>
{
private:
std::function<Ret(Args...)> m_f;
public:
wrapper (Cl const & cl, Ret(Cl::*m)(Args...) const)
: m_f{ [=](Args... as) { return (cl.*m)(as...); } }
{ }
Ret operator() (Args... args) const
{ return m_f(args...); }
};
In both cases, you could improve a little the operator()
adding perfect forwarding
template <typename ... As>
Ret operator() (As && ... as) const
{ return m_f(std::forward<As>(as)...); }
Template function wrapper
There is significant difference between:
(&Wrapper<decltype (fun)>::template invoke<T>);
and
(&Wrapper<decltype(&test)>::template invoke<&test>);
in the former you use T
which is obviously the type of the function you pass in the latter you provide the pointer to function to the invoke method. As invoke
method accepts non-type template parameter, here function pointer, the second code compiles correctly. Remember - you cannot mix non-type template parameters with type template parameters just like you cannot mix type template parameters with template template parameters.
Use member function as template argument to create a static wrapper
The simple answer for C++11 is: You can't!
From C++17 you are able to use auto
also for non type template parameters as a function pointer or member function pointer is not a type here and you have no syntax to describe your function pointer type.
In C++17 you can use it like this:
struct foo
{
void bar(){}
};
template <typename T, T>
struct helper;
template <typename T, typename R, typename... Args, R(T::*Func)(Args...)>
struct helper<R(T::*)(Args...), Func>
{
static void reg_handler(const char* name)
{
// ... here your code continues
}
};
template < auto T >
struct X
{
};
template <typename T, typename R, typename... Args, R(T::*Func)(Args...)>
struct X<Func>
{
static void register_handler( const char* name )
{
helper<R(T::*)(Args...), Func>::reg_handler(name);
}
};
int main()
{
X<&foo::bar>::register_handler("check");
}
How to write a template wrapper method for other class member functions?
Try this,
#include <algorithm>
#include <functional>
#include <iostream>
class A
{
public:
void foo(int x) {
std::cout << "Foo: " << x << std::endl;
}
void bar(int x, float y) {
std::cout << "Bar: " << x << ", " << y << std::endl;
}
};
class B
{
public:
void fooAndMore(int x) {
foobarWrapper(&A::foo, x);
}
void barAndMore(int x, float y) {
foobarWrapper(&A::bar, x, y);
}
template<typename T, typename... Args>
void foobarWrapper(T func, Args&&... args)
{
std::cout << "Start!" << std::endl;
auto caller = std::mem_fn( func); // Newly added lines
caller( A(), args...); // Newly added line
std::cout << "End!" << std::endl;
}
};
int main()
{
B b;
b.fooAndMore(1);
b.barAndMore(2, 3.5f);
}
output:
Start!
Foo: 1
End!
Start!
Bar: 2, 3.5
End!
See this link for more details std::mem_fn
How to declare the template argument for an overloaded function
You can wrap the function in a lambda, or pass a function pointer after casting it to the type of the overload you want to call or explicitly specify the template parameter:
use_funct([](){ do_something (); });
use_funct(static_cast<void(*)()>(do_something));
use_funct<void()>(do_something);
Wrapping it in a lambda has the advantage, that it is possible to defer overload resolution to use_func
. For example:
void do_something(int) {}
void do_something(double) {}
template<typename F> void use_funct(F funct) {
funct(1); // calls do_something(int)
funct(1.0); // calls do_something(double)
}
int main() {
use_funct([](auto x){ do_something (x); });
}
[...] possibly without referring to a function pointer?
I am not sure what you mean or why you want to avoid that. void()
is the type of the function, not a function pointer. If you care about spelling out the type, you can use an alias:
using func_type = void();
use_funct<func_type>(do_something);
Related Topics
Node Packages Not Building on Windows 8.1 - Missing Microsoft.Cpp.Default.Props
Why Do Some Includes Need the .H and Others Not
Call of Overloaded Function Is Ambiguous
Why Is Cmake Designed So That It Removes Runtime Path When Installing
Automatically Generate C++ File from Header
C++:What's the Easiest Library to Open Video File
Partial Ordering with Function Template Having Undeduced Context
Access Extern Variable in C++ from Another File
Convert a Number to a String with Specified Length in C++
Understand Op Registration and Kernel Linking in Tensorflow
Why Does Initializing an Extern Variable Inside a Function Give an Error
Which MACro to Wrap MAC Os X Specific Code in C/C++
Instantiate Class with or Without Parentheses
How to Get a List of Files in a Folder in Which the Files Are Sorted with Modified Date Time
How to Use C Source Files in a C++ Project