Parameterization template by function name C ++ 11

Having the following features

void print(int a) { cout << a << endl; } void print(std::string a) { cout << a << endl; } 

You can do the following pattern

 template <class T> void printT(T a) { print(a); } 

Is there any mechanism for parameterizing a function name? Something like that:

 template <class T, class F> void anyT(T a) { F(a); } 

I do not need to be a function template, just some mechanism to achieve the same.

+6
source share
6 answers

Yes, you could pass a caller as a pointer to a function that takes T as an input value, as shown below:

 template <class T> void anyT(T a, void(*f)(T)) { f(a); } 

Live demo

+1
source

You can pass a function as a parameter.

 template <class T, class F> void anyT(T a, F f) { f(a); } 

The advantage of this compared to passing a function pointer to an argument type pattern suggested by 101010 is that it works with both function pointers and functors (instances of any type that implement operator() , such as lambdas.

The disadvantage is that getting a function pointer of an overloaded function can be difficult in the context of a freely templated parameter. You will need to use

 void (*f)(int) = print; anyT(a, f); 

Or, conversely, wrap it in lambda as suggested by GuyGreer.

+1
source

I personally would go with the solution 101010, however you do not seem to want to pass a function pointer as a function parameter, but rather only as a template parameter. Here's how you can do it:

  #include <string> template <class T, void(*func)(T)> void anyT(T t) { func(t); } void print(int i){} void print(std::string s){} int main() { anyT<int, print>(1); anyT<std::string, print>("hello"); } 

Unfortunately, this means that you must specify template parameters for a function that is a drag and drop each time.

A better solution, I think, would be to just use a generic template parameter and lambda:

  template <class T, class F> void anyT(T t, F f) { f(t); } auto printT = [](auto i){print(i);} anyT(0, printT); 

A lambda is necessary, because passing print directly will be ambiguous, the compiler will not know if you have print(int) or print(std::string) value.

+1
source

This is a useful macro:

 #define OVERRIDES_OF(...) [](auto&&...args)->decltype(auto){ return __VA_ARGS__ (decltype(args)(args)...);} 

the result is a barrage lambda that is sent to the specified token.

Using:

 static const auto printT = OVERRIDES_OF(print); 

now printT is an object that wraps all print overrides.

+1
source

trying to understand the meaning here. In C ++ 14, we have lambdas with auto arguments. Will this be resolved?

 #include <iostream> int main() { int a = 1; std::string str = "string"; auto print = [] (const auto& a) { std::cout << a << std::endl; }; print(a); print(str); } 
0
source

You can pass a function using a function pointer:

 template <class T> void anyT(T a, void(*F)(T)) { F(a); } 

but then you cannot pass lambda:

 auto printStr = [](std::string a) { cout << a << endl; }; anyT(foo, printStr); // This won't compile 

An alternative approach would be to use std::function :

 template <class T> void anyT(T a, std::function<void(T)> F) { F(a); } 

or general template parameter:

 template <class T, class F> void anyT(T a, F func) { func(t); } 

This has the disadvantage that it cannot resolve overloaded functions, but you can use a helper function:

 template<typename F> std::function<F> make_function(F *funPtr) { return std::function<F>(static_cast<F*>(funPtr)); } 

and call anyT as follows:

 string foo = "foo"; anyT(foo, make_function<void(std::string)>(&print)); 
0
source

All Articles