Why std::bind can't be param of parameters pack? - c++

I'd like to use parameters pack, but find the problem.
Some code:
template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
auto f11 = std::bind(func, args...);
f11();
}
void print(const char* string)
{
std::cout << string << std::endl;
}
All of this works well:
f([] (const char* additional, const char* more) {
std::cout << "hello ( " << additional << ", " << more << " )" << std::endl;
}, "additional text", "and one more");
auto printFunction = std::bind(&print, std::placeholders::_1);
printFunction("hello from print bind");
f(print, "hello from print directly");
but if i would like to give std::function to parameters pack:
f([] (std::function<void(const char*)> printParamFunc) {
printParamFunc("hello from print from std::function");
}, printFunction);
application no more compiles.
So, what the problem to use function as parameter in pack?
Thanks.
UPDATE:
if change code of f to:
template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
func(args...);
}
it works well, but i wouldn't like to execute this function here, i wanna create function and pass it like param.
UPDATE2:
Code execution example: http://ideone.com/gDjnPq
UPDATE3:
Clear code with compilation error: http://ideone.com/50z7IN

I understand the situation a bit better now.
Problem can be retroduced by this code:
void print(const char* string)
{
std::cout << string << std::endl;
}
int main(int argc, char ** argv)
{
auto lambda = [] (std::function< void ( const char * ) > printParamFunc) {
printParamFunc("hello from lambda!");
};
std::bind(lambda, std::bind(print, std::placeholders::_1))();
}
Nested std::bind trying to evaluate and fails with conversion _1 to const char *. It is specific of std::bind.
We need analogue of boost::bind::protect -- functor storing other functor -- and it is solve problem:
template <class F>
struct lazy_evaluate {
typedef typename F::result_type T;
explicit lazy_evaluate(F f) : f_(f) {}
template <class... Args>
T operator()(Args&&... args)
{
f_(std::forward<Args>(args)...);
}
private:
F f_;
};
template <class F>
lazy_evaluate<F> lazy(F f)
{
return lazy_evaluate<F>(f);
}
nested std::bind now looks like:
std::bind(lambda, lazy(std::bind(print, std::placeholders::_1)))();
and works well.

Related

C++ Function with variable number and types of arguments as argument of another function

I would like to create function calling another function and printing its arguments.
It should be compatible with many functions (returning the same result) with many combinations of variables of arguments.
I would like to have something like this:
int fun1(){}
int fun2(int i){}
int fun3(std::string s, int i){}
void execute_and_print(std::function f, ...)
{
///code
}
int main()
{
execute_and_print(&fun1);
execute_and_print(&fun2, 3);
execute_and_print(&fun3,"ff",4);
}
It could print:
executed function with arguments:
executed function with arguments: 3
executed function with arguments: ff, 4
Is it even possible in C++?
In C++17 it is very simple
template <typename F, typename... Args>
void execute_and_print(F f, Args... args)
{
(std::cout << ... << args);
f(args...);
}
Prior to that there is extra ceremony
template <typename F, typename... Args>
void execute_and_print(F f, Args... args)
{
int dummy[] = { (static_cast<void>(std::cout << args), 0)... };
f(args...);
}
It is not foolproof, but any possible errors will be caught at compile time (ie. the code will not compile). It should work file, as long as the provided parameters match those of the called function, and a matching << operator exists for each parameter.
template<class Fn, class...Args>
void execute_and_print(Fn fn, Args...args) {
int f[sizeof...(Args)] = { (std::cout << args << ", ", 0)... };
fn(args...);
}
Refer to https://en.cppreference.com/w/cpp/language/parameter_pack. The sizeof... command is actually the number of elements, not their combined size.
You can use templates to get it done,
template <class... Args>
void RunThrough(Args&& ... args)
{
([&](auto& input)
{
std::cout << input << ", ";
} (args), ...);
}
template<class Func, class... Args>
decltype(auto) execute_and_print(Func f, Args&&... args)
{
f(args...);
std::cout << "executed function with arguments: ";
RunThrough(args...);
std::cout << std::endl;
}
You can use lambdas, std::function objects and function pointers in this.
Reference: https://stackoverflow.com/a/60136761/11228029

How to cast "void (MyClass::*)(int)" to "void (*)(int)"?

I've looking for how to cast class member to C-style callback.
Recentrly i found answer with special bind hack allows to bind class members to C-style callbacks:
https://stackoverflow.com/a/39524069/5405443
I have this working code to bind function MyClass::f to C function f:
But i want to avoid explicit passing cb_type as template parameter to c_bind function.
In provided example CB has type void (*)(int) and Func template parameter has void (MyClass::*)(int) type.
template<typename CB, typename Func, typename... Params>
CB* c_bind(std::_Bind<Func(Params...)> function) {
return Callback<typename ActualType<CB>::type, __COUNTER__, Func>::getCallback(function);
}
typedef void (cb_type)(int);
class MyClass {
public:
void f(int x) {
std::cout << "Hello from MyClass::f(int), value: " << x << std::endl;
}
};
int main() {
MyClass mc;
auto f = c_bind<cb_type>(std::bind(&MyClass::f, mc, std::placeholders::_1));
// ^ how to avoid explicit callback type declaration here?
f(10);
return 0;
}
Also i found this piece of code (https://gist.github.com/vikchopde/73b62314379f733e8938f11b246df49c) for "unwrapping" some kind of functions.
bool ok = fu::is_unwrappable<decltype(&MyClass::f)>::value; // always false
// fu::unwrap_function<decltype(&MyClass::f)>::type::function_ptr blah; // won't compile
but it won't work by unknown to me reason.
My question is there any workaround to extract return type and args list from type with class-memeber pointer like void (MyClass::*)(int) and contruct C-like type void (*)(int) ?
Thank you for any help!
Well, in C++17, you are allowed to pass an arbitrary non-type parameter to a class with template<auto>. Therefore, we could store MyClass::f as a template parameter and parse its type with decltype. After passing this type to another templated class, we are able to extract desired types using template specialization.
The code below shows how to construct a C-style function wrapper<>::func_type.
Since you seem to bind an object to its member function, I additionally write the demo code to do this by invoking wrapper<>::bind. Hope it helps.
class MyClass {
public:
void f(int x) {
std::cout << "Hello from MyClass::f(int), value: " << x << std::endl;
}
};
void f(int x) {
std::cout << "Hello from f(int), value: " << x << std::endl;
}
template<auto F>
struct wrapper
{
template<typename> struct inner;
template<class Cls, typename Ret, typename... Args>
struct inner<Ret(Cls::*)(Args...)>
{
using func_type = Ret(Args...);
static auto bind(Cls *obj)
{
return [=](Args ...args){
return (obj->*F)(std::forward<Args>(args)...);
};
}
};
using func_type = typename inner<decltype(F)>::func_type;
static const constexpr auto bind = inner<decltype(F)>::bind;
};
int main() {
MyClass mc;
auto h = wrapper<&MyClass::f>::bind(&mc);
h(10);
using func_t = typename wrapper<&MyClass::f>::func_type;
std::function<func_t> g = f;
g(1);
return 0;
}
First of all i would like to thank #Dappur for nice example. Using your guide i will rewrite my ugly bind interface with std::_Bind usage later. Also i want to thank #Sam Varshavchik for mentioning that set of C++ books. I'll start reading it to become C++ grandmaster like you to learn how "why i cannot cast it like this". But unfortunately with my poor c++ experience I can still do it now. Here is working code:
template<class T, unsigned int n, class CallerType>
struct CallbackWrapper;
template<class Ret, class... Params, unsigned int n, class CallerType>
struct CallbackWrapper<Ret(Params...), n, CallerType> {
static auto get(std::function<Ret(Params...)>&& fn) -> Ret(*)(Params...) {
func = fn;
return static_cast<Ret(*)(Params...)>(CallbackWrapper<Ret(Params...), n, CallerType>::callback);
}
private:
static std::function<Ret(Params...)> func;
static Ret callback(Params... args) {
return func(args...);
}
};
template<class Ret, class... Params, unsigned int n, class CallerType>
std::function<Ret(Params...)> CallbackWrapper<Ret(Params...), n, CallerType>::func;
template<typename T>
struct lambda_to_stdf {
using type = void;
};
template<typename Ret, typename Class, typename... Args>
struct lambda_to_stdf<Ret(Class::*)(Args...) const> {
using type = std::function<Ret(Args...)>;
};
template<class Ret, class Cls, class... Args1, class... Args2>
auto c_bind(std::_Bind<Ret(Cls::*(Cls, Args1...))(Args2...)> function) -> Ret(*)(Args2...) {
return CallbackWrapper<Ret(Args2...), __COUNTER__, Ret(Cls::*(Cls, Args1...))(Args2...)>::get(std::move(function));
}
template<class Ret, class... Args>
auto c_bind(std::function<Ret(Args...)> function) -> Ret(*)(Args...) {
return CallbackWrapper<Ret(Args...), __COUNTER__, std::function<Ret(Args...)>>::get(std::move(function));
}
template<class F>
auto c_bind(F function) -> decltype(c_bind((typename lambda_to_stdf<decltype(&F::operator())>::type)(function))) {
return c_bind((typename lambda_to_stdf<decltype(&F::operator())>::type)(function));
}
Usage:
class MyClass {
public:
void f(int x) {
std::cout << "Hello from MyClass::f(int), value: " << x << std::endl;
}
};
int main() {
MyClass mc;
auto f = c_bind(std::bind(&MyClass::f, mc, std::placeholders::_1));
f(10);
std::function<void(int)> stdf = [](int v) {
std::cout << "hello from std::function, value: " << v << std::endl;
};
auto f2 = c_bind(stdf);
f2(100);
auto f3 = c_bind([](int v) -> int {
std::cout << "hello from lambda, value: " << v << std::endl;
return 5.0f;
});
f3(1000);
return 0;
}
Hope it will be helpful for someone.

I want strip argument from variable args by using template meta programming

I am new to template meta programming. I want to strip args from variable argument in c++. I am making a function which will push_back() element to any type of container. Its very easy to do in C++ 17 but i want to provide support for C++ 11 . Please find the code below push_back() function implementation i am looking for. Please avoid va_start(), va_end() c style solution.
#include <iostream>
#include <vector>
template<class Container, class T, class... Args>
void push_back(Container& con, T tail, Args... args);
template<class T>
T get_tail(T data) {
return data;
}
template<class T, class ...Args>
T get_tail(T& tail, Args&... args) {
return tail;
}
template<class Container , class T,class... Args>
void push_back(Container& con, T tail,Args... args ) {
//C++ 17 ((con.push_back(args), ...);
con.push_back(tail);
std::cout << (tail) << std::endl;
T newTail = get_tail(args...);
push_back(con,newTail,args...);
}
template<typename T, typename... Args>
bool pair_comparer(T a, T b, Args... args) {
return a == b && pair_comparer(args...);
}
int main()
{
std::vector<int> v_int;
push_back(v_int,1,2,3,4 );
std::cout << "Hello World!\n";
for (auto iter = v_int.begin(); iter != v_int.begin(); iter++) {
std::cout << "=== " << *iter << " ===" << std::endl;
}
}
You've already stripped the first argument away when you did
void push_back(Container& con, T tail, Args... args ) {
tail is the first argument and args is the rest, so your recursive call at the end simply needs to say
pus_back(con, args...)
No need for any of this get_tail hackery. Then, simply have another overload of push_back that looks like this.
template <class Container>
void push_back(Container& con) {
// A whole lot of nothing happens here...
}
That handles the base case, and the function you already wrote (with the one minor modification) handles the recursive case.
Not sure to understand what do you exactly want but...
Are you sure you need recursion?
You can develop something similar the C++17 way unpacking the variadic args..., using the initialization of an unused C-style array, as follows
template <typename Container, typename ... Args>
void push_back (Container & con, Args ... args ) {
using unused = int[];
(void)unused { 0, ((void)con.push_back(args), std::cout << args << std::endl, 0)... };
}
Or simply as follows
template <typename Container, typename ... Args>
void push_back (Container & con, Args ... args ) {
using unused = int[];
(void)unused { 0, ((void)con.push_back(args), 0)... };
}
if the std::cout part is just for debugging purposes.
The problem in your code is that you call push_back inside of itself with the same number of arguments. This makes the recursion infinite. Instead you need to "strip" one argument each time. And certainly provide the recursion base. Like this:
template<class Container>
void push_back(Container& con) {
}
template<class Container , class T,class... Args>
void push_back(Container& con, T tail, Args... args ) {
con.push_back(tail);
std::cout << (tail) << std::endl;
push_back(con, args...);
}
int main()
{
std::vector<int> v_int;
push_back(v_int,1,2,3,4 );
std::cout << "Hello World!\n";
for (auto x : v_int)
std::cout << "=== " << x << " ===" << std::endl;
}

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);

stringstream with recursive variadic function?

I want to be able to combine multiple different arguments into a single string using ostringstream. That way I can log the resulting single string without any random issues.
I got this far:
template <typename T>
void MagicLog(T t)
{
std::cout << t << std::endl;
}
template<typename T, typename... Args>
void MagicLog(T t, Args... args) // recursive variadic function
{
std::cout << t << std::endl;
MagicLog(args...);
}
template<typename T, typename... Args>
void LogAll(int logType, T t, Args... args)
{
std::ostringstream oss;
MagicLog(t);
MagicLog(args...);
//Log(logType, oss.str());
}
So I need to replace std::cout with the oss that I made in the LogAll function, I tried passing it as an argument to the other functions but it was complaining about a "deleted function"...
So: How can I get a recursive variadic function to accept another parameter, the ostringstream?
I don't really understand your problem. Just like what you did with your LogAll function, passing an ostream& as first parameter works like a charm:
#include <iostream>
#include <sstream>
template <typename T>
void MagicLog(std::ostream& o, T t)
{
o << t << std::endl;
}
template<typename T, typename... Args>
void MagicLog(std::ostream& o, T t, Args... args) // recursive variadic function
{
MagicLog(o, t);
MagicLog(o, args...);
}
template<typename... Args>
void LogAll(int logType, Args... args)
{
std::ostringstream oss;
MagicLog(oss, args...);
std::cout << oss.str();
}
int main()
{
LogAll(5, "HELLO", "WORLD", 42);
}
It was also possible to eliminate the duplicate code from your MagicLog function.