Converting std::function<void(string, string)> to a generic std::function<void()> - c++

I'm trying somme features of c++0x (under gcc 4.5):
I know it's possible to convert a std::function<void(string, string)> to std::function<void()> when arguments are specified at compilation; but is it possible when arguments are submitted at runtime ?
#include <iostream>
#include <utility>
#include <string>
using namespace std;
using namespace placeholders;
class Print{
public:
void print1(string s1, string s2){ cout<<"s1 : "<<s1<<" s2 : "<<s2<<endl;}
void print2(string s1){ cout<<"s1 : "<<s1<<endl;}
};
Print p = Print();
function<void(string, string)> f1(bind(&Print::print1, &p, _1, _2));
function<void()> f = f1;
I get those errors :
/usr/include/c++/4.5/functional:2103:6: instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = std::function<void(std::basic_string<char>, std::basic_string<char>)>, _Res = void, _ArgTypes = {}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<void()>::_Useless]’
../src/Cpp0x_test.cpp:345:34: instantiated from here
/usr/include/c++/4.5/functional:1713:9: error: no match for call to ‘(std::function<void(std::basic_string<char>, std::basic_string<char>)>) ()’
/usr/include/c++/4.5/functional:2111:5: note: candidate is: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void, _ArgTypes = {std::basic_string<char>, std::basic_string<char>}]
Actually I need to do :
function<void(string, string)> f1(bind(&Print::print1, &p, _1, _2));
function<void(string)> f2(bind(&Print::print2, &p, _1));
function<void()> fx1 = f1;
function<void()> fx2 = f2;
std::vector<function<void()> > vec;
vec.push_back(fx1);
vec.push_back(fx2);
//then, later
function<void()> call1 = vec[0];
function<void()> call2 = vec[1];
call1("test1", "test2");
call2("test3");

The question doesn't really make sense.
I know it's possible to convert a std::function<void(string, string)>
to std::function<void()> when arguments are specified at compilation;
but is it possible when arguments are submitted at runtime ?
If you're talking about doing this to set the arguments "at compilation":
string arg1,arg2;
function<void()> f = bind(f1,arg1,arg2); // f = [=] { f1(arg1,arg2); };
this is actually doing the binding at runtime. Whatever value those arguments have when bind is called, even if they are set at runtime, say, from user input, the calling f() will use those runtime values.
Perhaps you mean that the above code binds f1 to the value of arg1 and arg2 at the time bind is called, and that changing the values of the objects used in bind later on doesn't affect the values used in calls to f(). There's a way around that:
string arg1,arg2;
function<void()> f =
bind(f1,std::ref(arg1),std::ref(arg2)); // f = [&,f1] { f1(arg1,arg2); };
This causes f to hold references to the objects instead of just the static value used at the time bind is called. You can now assign new values to arg1 and arg2 and when f() is called the new values will be used. Note that you have to make sure that the references held by f remain valid and don't become dangling references so long as f can still be called.
function<void(string)> foo = [](string s){ cout << s; };
string arg = "Hello,";
function<void()> bar = bind(foo,ref(arg)); // bar = [=,&arg] { foo(arg); };
bar(); // prints "Hello,"
arg = " World!"
bar(); // prints " World!"

Its possible using bind aswell:
string arg1, arg2;
function<void()> f(bind(f1, arg1, arg2));
f(); // calls f1(arg1, arg2) with their values at the time of bind

Let's see if I understand your requirement.
Why don't you just store the arguments in a vector instead of the functions?
std::vector<std::tuple<std::string,std::string>> v;
v.push_back(std::make_tuple("a", "b")); // repeat
// Later that day...
for(auto& t : v) {
f(get<0>(t), get<1>(t));
}

Related

Saving references

Consider the following uncomplicated code:
#include <thread>
#include <utility>
#include <vector>
#include <atomic>
#include <queue>
#include <iostream>
#include <functional>
using namespace std;
template<class It, class Fun>
void parallel_for(size_t num_threads, It first, It end, const Fun& fun) {
std::queue<std::thread> ts;
for (It it = first; it != end; ++it) {
if (std::distance(first, it) % num_threads == 0) {
fun(*it);
} else {
if (ts.size() == num_threads-1) {
ts.front().join();
ts.pop();
}
ts.push(std::thread(fun, std::ref(*it)));
}
}
while (not ts.empty()) {
ts.front().join();
ts.pop();
}
}
int main() {
std::atomic_int counter = 1;
auto lam = [&counter](auto& vl) {
vl = std::pair(counter++, -1);
};
// The following usage of std::ref works okay:
pair<int, int> x;
auto blam = bind(lam, ref(x));
blam();
// Nevertheless, the next line fails:
// lam(ref(x));
// As well as the next two ones:
// vector<pair<int, int>> v = {{4, 2}};
// parallel_for(thread::hardware_concurrency(), begin(v), end(v), lam);
return 0;
}
GCC's error on the last two lines, in particular, is
In file included from ./src/csc_cpp/passing_lambdas.cpp:1:
/usr/include/c++/10/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = const main()::<lambda(auto:1&)>&; _Args = {std::reference_wrapper<std::pair<int, int> >}; <template-parameter-1-3> = void]’:
./src/csc_cpp/passing_lambdas.cpp:22:26: required from ‘void parallel_for(size_t, It, It, const Fun&) [with It = __gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >; Fun = main()::<lambda(auto:1&)>; size_t = long unsigned int]’
./src/csc_cpp/passing_lambdas.cpp:47:71: required from here
/usr/include/c++/10/thread:136:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
136 | typename decay<_Args>::type...>::value,
| ^~~~~
I am sure this is a trivial matter, but I am anyway struggling to understand this. I think I have been following the available examples on std::thread::thread()'s intended use quite closely, but this does not compile. What am I doing wrong?
First, let me clarify, because I'm not sure if it's obvious: the trick behind std::ref is that it returns an object of type std::reference_wrapper<T>, so you can use the result as object, but the object is implicitly convertible to T&, so it can be substituted where T& is needed.
lam(ref(x)); fails because you use auto in lam. Compiler doesn't know that you want vl to be std::pair<int, int>&, it deduces from what it gets. std::ref returns a temporary of std::reference_wrapper<std::pair<int, int>>, which cannot be bound to non-const reference. Use explicit type in lambda and it compiles:
auto lam = [&counter](std::pair<int, int>& vl) {
vl = std::pair(counter++, -1);
};
lam(std::ref(x));
Alternatively, you can explicitly convert to std::pair<int, int>& using get() or static_cast
auto lam = [&counter](auto& vl) {
vl = std::pair(counter++, -1);
};
lam(std::ref(x).get());
lam(static_cast<std::pair<int, int>&>(std::ref(x)));
The second part with parallel_for has exactly the same issue, you pass rvalue of std::reference_wrapper to lam.
About
lam(ref(x));
x is an lvalue while the ref(x) is a temporary reference_wrapper. You can not grab a temporary with an lvalue reference in your lam through auto&.
for that line, you can simply use
lam(x);

std::async with shared pointer templated member functions

I'm working on implementing multi-threading in a project, but am running into a wall when it comes to some more complicated uses of std::async. I want to call a member function on a templated object and pass in an argument as a parameter, but I can't get it to work when the template holds a shared pointer.
It's pretty simple to use std::async on member functions, and even templated member functions. I've seen plenty of answers around stack overflow for this specific usage. I've even run some test cases myself:
#include <thread>
#include <future>
#include <iostream>
class Bar
{
public:
Bar () {}
double data;
};
template <typename T>
class Foo
{
public:
Foo () {}
T set_data (T d) { data = d; return data; }
private:
T data;
};
#include "./foo.h"
#include <memory>
int main (int argc, char **argv)
{
/**
* Works fine
*/
Foo<int> foo1;
auto fut1 = std::async(std::launch::async, &Foo<int>::set_data, &foo1, 42);
fut1.wait();
std::cout << fut1.get() << std::endl;
return 0;
}
This example compiles perfectly fine in gcc 7.4.0 and returns 42 as expected.
My problem comes in when I use shared_ptr in the template. Using the same Foo and Bar classes from above:
#include "./foo.h"
#include <memory>
int main (int argc, char **argv)
{
/**
* Doesn't work
*/
auto foo2 = std::make_shared<Foo<std::shared_ptr<Bar>>>;
auto br = std::make_shared<Bar>;
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, &foo2, bar);
fut2.wait();
std::cout << fut2.get()->data << std::endl;
return 0;
}
I get this error when compiling g++ -pthread test.cpp -o test
test.cpp: In function ‘int main(int, char**)’:
test.cpp:20:94: error: no matching function for call to ‘async(std::launch, std::shared_ptr<Bar> (Foo<std::shared_ptr<Bar> >::*)(std::shared_ptr<Bar>), Foo<std::shared_ptr<Bar> >*, std::shared_ptr<Bar> (*&)())’
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, &foo2, bar);
^
In file included from ./foo.h:2:0,
from test.cpp:1:
/usr/include/c++/7/future:1712:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^~~~~
/usr/include/c++/7/future:1712:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = std::shared_ptr<Bar> (Foo<std::shared_ptr<Bar> >::*)(std::shared_ptr<Bar>); _Args = {Foo<std::shared_ptr<Bar> >*, std::shared_ptr<Bar> (*&)()}]’:
test.cpp:20:94: required from here
/usr/include/c++/7/future:1712:5: error: no type named ‘type’ in ‘class std::result_of<std::shared_ptr<Bar> (Foo<std::shared_ptr<Bar> >::*(Foo<std::shared_ptr<Bar> >*, std::shared_ptr<Bar> (*)()))(std::shared_ptr<Bar>)>’
/usr/include/c++/7/future:1745:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...)
async(_Fn&& __fn, _Args&&... __args)
^~~~~
/usr/include/c++/7/future:1745:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {std::shared_ptr<Bar> (Foo<std::shared_ptr<Bar> >::*)(std::shared_ptr<Bar>), Foo<std::shared_ptr<Bar> >*, std::shared_ptr<Bar> (*&)()}]’:
test.cpp:20:94: required from here
/usr/include/c++/7/future:1745:5: error: no type named ‘type’ in ‘class std::result_of<std::launch(std::shared_ptr<Bar> (Foo<std::shared_ptr<Bar> >::*)(std::shared_ptr<Bar>), Foo<std::shared_ptr<Bar> >*, std::shared_ptr<Bar> (*)())>’
I thought this maybe was because the reference & wasn't working in the proper order with all those angle brackets for the templates, so I tried using some parentheses:
#include "./foo.h"
#include <memory>
int main (int argc, char **argv)
{
/**
* Doesn't work
*/
Foo<std::shared_ptr<Bar>> foo2;
Bar bar;
auto fut2 = std::async(std::launch::async, &(Foo<std::shared_ptr<Bar>>::set_data), &foo2, bar);
fut2.wait();
std::cout << fut2.get().data << std::endl;
return 0;
}
Which results in a shorter error which I also don't understand.
test.cpp: In function ‘int main(int, char**)’:
test.cpp:20:75: error: invalid use of non-static member function ‘T Foo<T>::set_data(T) [with T = std::shared_ptr<Bar>]’
auto fut2 = std::async(std::launch::async, &(Foo<std::shared_ptr<Bar>>::set_data), &foo2, bar);
I am confused why the shared pointers all of a sudden make a difference, and I'm guessing it has to do with type deduction? Any help is appreciated.
EDIT
Thanks to those that responded, here is the solution. The parentheses are not required, and some shared_ptrs were missing.
#include "./foo.h"
#include <memory>
int main (int argc, char **argv)
{
Foo<std::shared_ptr<Bar>> foo2;
auto bar = std::make_shared<Bar>(2.5);
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data), &foo2, bar;
fut2.wait();
std::cout << fut2.get()->data << std::endl;
return 0;
}
There are some issues, I think that using a lambda might help you clarify what is going on:
int main (int argc, char **argv)
{
Foo<std::shared_ptr<Bar>> foo2;
Bar bar;
auto op = [foo2, bar]() mutable {return foo2.set_data(std::make_shared<Bar>(bar));};
auto fut2 = std::async(std::launch::async, op);
fut2.wait();
std::cout << fut2.get()->data << std::endl;
return 0;
}
You have to pass to the set_data a shared_ptr to Foo. Secondly, the set_data is not const-qualified, so you need a mutable lambda.
Lastly, the future, when returning though get(), will give you a shared_ptr to Bar so you need the operator -> .
You can make the code more efficient moving Foo2 and Bar inside the lambda, but I am trying to keep the answer simple, in particular because I do not know if you want, in your use case to re-use Foo2 and Bar, but you can consider moving inside the lambda.
Regarding your specific code, the following is compiling in g++ 9.1 with C++14, see https://godbolt.org/z/DFZLtb
int main (int argc, char **argv)
{
Foo<std::shared_ptr<Bar>> foo2;
Bar bar;
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, &foo2, std::make_shared<Bar>());
fut2.wait();
std::cout << fut2.get()->data << std::endl;
return 0;
}
You need to provide a shared_ptr<Bar>as argument and not a Bar and you need to remove the parenthesis around Foo<std::shared_ptr<Bar>>::set_data.
You just have some typos in your code, in first shared_ptr example you pass shared_ptr<Foo> instead of raw ptr Foo* to your function. In the second example first argument Foo* is correct, but second one is Bar instead of shared_ptr<Bar>. Here you have the working example:
class Bar
{
public:
Bar () {}
double data;
};
template <typename T>
class Foo
{
public:
Foo () {}
T set_data (T d) { data = d; return data; }
private:
T data;
};
#include <future>
TEST(xxx, yyy) {
Foo<std::shared_ptr<Bar> > foo;
auto bar = std::make_shared<Bar>();
bar->data = 42;
auto futureResult = std::async(std::launch::async,
&Foo<std::shared_ptr<Bar> >::set_data, &foo, bar);
std::cout << futureResult.get()->data << std::endl;
}
As a side note, if you need to run async operation on some data inside your Foo class, better provide the interface that executes this async operation inside your class and returns the future.
std::future<T> runAsyncOper(const T& data);
Your first example with the shared pointer doesn't pass a shared pointer to std::async as a last parameter, it passes a pointer to function (you didn't add the parentheses)
int main()
{
/**
* Works :)
*/
Foo<std::shared_ptr<Bar>> foo2;
auto br = std::make_shared<Bar>();
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, &foo2, br);
fut2.wait();
std::cout << fut2.get()->data << std::endl;
return 0;
}
Problem is that you passed wrong types of arguments to std::async and used incorrectly std::make_shared.
Minimal modification to your code:
auto foo2 = std::make_shared<Foo<std::shared_ptr<Bar>>>();
auto bar = std::make_shared<Bar>();
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, foo2, bar);
fut2.wait();
std::cout << fut2.get()->data << std::endl;
https://wandbox.org/permlink/3YXG56ahFKrZs8GB

C++ bound function passed to a lambda

I have the below code where I am trying to print the multiplication table of 10.
I have bound the function multiply with two parameters 5 and 2. I am passing the bound function to create a lambda. And then I am attempting to pass the lambda to the for_each loop to print the Multiplication Table. I intutively kind of know that I may be pushing it a bit too far. But I don't know the exact reason. Can someone explain.
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <functional>
#include <future>
#include <array>
#include <unistd.h>
using namespace std;
using namespace std::placeholders;
int multiply(int a, int b, int c)
{
return a*b*c;
}
int main()
{
auto f = std::bind(multiply, 5, 2, _1);
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl; };
vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
for_each(vec.begin(), vec.end(), f1);
return 0;
}
The error that I am getting is shown below.
/home/karthik/Workspace/cpppen/learning/main.cpp: In function ‘int main()’:
/home/karthik/Workspace/cpppen/learning/main.cpp:26:107: error: conversion from ‘main()::<lambda(int)>’ to non-scalar type ‘std::function<int(int, int, int)>’ requested
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl;};
^
In file included from /usr/include/c++/7/algorithm:62:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:6:
/usr/include/c++/7/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Funct = std::function<int(int, int, int)>]’:
/home/karthik/Workspace/cpppen/learning/main.cpp:30:40: required from here
/usr/include/c++/7/bits/stl_algo.h:3884:5: error: no match for call to ‘(std::function<int(int, int, int)>) (int&)’
__f(*__first);
~~~^~~~~~~~~~
In file included from /usr/include/c++/7/functional:58:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:8:
/usr/include/c++/7/bits/std_function.h:701:5: note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes = {int, int, int}]
function<_Res(_ArgTypes...)>::
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
I am passing a function with two bound and one placeholder parameter.
No you're not. Your lambda looks like this:
[f](int a) {
cout << "Multiplication Table (10) :" << f(a) << endl;
}
That is the callable object that you are passing to std::function. Now, the lambda is callable with only one argument, not three. Notice:
[/*...*/](int a){ /*...*/ }
// ^^^^^
// one parameter
Likewise, f is a callable object with only one parameter. You can't call it with three arguments, because you've bound two parameters to specific values, so, for all intents and purposes, there are no three parameters. Maybe this makes it more clear:
auto add = [](int a, int b) { return a + b; };
auto addTo5 = [&add](int a) { return add(a, 5); };
add(1, 2); // ok, lambda takes two parameters
addTo5(3); // ok, lambda takes one parameter
addTo5(1, 2); // not ok, lambda doesn't take two parameters
std::function<int(int, int)> fadd = add; // ok
std::function<int(int)> faddTo5 = addTo5; // ok
std::function<int(int, int)> faddTo5fail = addTo5; // not ok, same reason
// addTo5 is approximately what std::bind does: It generates an object which has
// several variables "fixed", and so only takes the placeholder arguments that aren't
// specified.
So, the fix is to change f1's type to reflect what you are actually storing; a callable that takes an int and returns nothing:
std::function<void(int)> f1 = /*...*/;
// ^^^^
// lambda returns nothing

How to use boost::bind correctly with a map of function pointers

I am trying to achieve something like this but getting boost bind related errors
#include <map>
#include "boost/assign.hpp"
#include <boost/foreach.hpp>
#include <string>
#include <boost/function.hpp>
#include <boost/bind.hpp>
struct myStruct_t
{
int getInt () {return 1;};
};
int foo( myStruct_t* m, std::string str)
{
if(str == "A")
{
return m->getInt();
}
else if (str == "B")
{
return 2;
}
else
{
return 3;
}
}
typedef std::map<std::string, boost::function<int(myStruct_t*, std::string)> > Map_t;
Map_t myMap = boost::assign::map_list_of ("Jake", boost::bind((&foo, _1), "A")
("Ken", boost::bind((&foo, _1), "B")
("Pete", boost::bind((&foo, _1), "C");
int main ()
{
std::vector<std::string> myVal;
myVal.push_back("Jake");
myVal.push_back("Ken");
myVal.push_back("Pete");
myStruct_t myStruct;
BOOST_FOREACH( const std::string& aStr, myVal)
{
Map_t::const_iterator iter = myMap.find(aStr);
if(iter != myMap.end())
{
int myInt = (iter->second)(myStruct);
}
}
return 0;
}
The errors I am getting are
In file included from /usr/local/boost-1.60.0/include/boost/bind.hpp:22:0,
from prog.cc:6:
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp: In instantiation of 'boost::_bi::result_traits<boost::_bi::unspecified, boost::arg<1> >':
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp:1212:48: instantiated from 'boost::_bi::bind_t<boost::_bi::unspecified, boost::arg<1>, boost::_bi::list1<boost::_bi::value<const char*> > >'
prog.cc:32:81: instantiated from here
/usr/local/boost-1.60.0/include/boost/bind/bind.hpp:75:37: error: no type named 'result_type' in 'struct boost::arg<1>'
prog.cc:34:82: error: expected ')' before ';' token
prog.cc: In function 'int main()':
prog.cc:50:48: error: no match for call to '(const boost::function<int(myStruct_t*, std::basic_string<char>)>) (myStruct_t&)'
/usr/local/boost-1.60.0/include/boost/function/function_template.hpp:765:17: note: candidate is: result_type boost::function2<R, T1, T2>::operator()(T0, T1) const [with R = int, T0 = myStruct_t*, T1 = std::basic_string<char>, result_type = int]
It seems I am puzzled the way boost::bind is used. Can someone please help me doing it correctly? Many Thanks.
The function signature expected at the call site is int(myStruct*)
because of this line (I added the & to remove a logic error):
int myInt = (iter->second)(&myStruct);
in which case the declaration of the map should be:
typedef std::map<std::string, boost::function<int(myStruct_t*)> > Map_t;
Map_t myMap = boost::assign::map_list_of
("Jake", boost::bind(&foo, boost::placeholders::_1, std::string("A")))
("Ken", boost::bind(&foo, boost::placeholders::_1, std::string("B")))
("Pete", boost::bind(&foo, boost::placeholders::_1, std::string("C")));
And then you're good to go.
explanation:
boost[std]::bind returns a function object which is designed to accept only the parameters that are mentioned as placeholders in the bind expression.
This means that the function that is finally called will often have more arguments than the function object returned by bind
so in your case, foo has the following signature:
int foo( myStruct_t* m, std::string str)
i.e. takes two arguments and returns an int.
However at the point of the call to bind:
boost::bind(&foo, boost::placeholders::_1, std::string("A"))
What we're saying is "capture the function foo and the second argument (a string). Return me a function object that requires one argument (_1) and forward that argument as the first argument to foo while passing the bound string as the second argument.
so given:
auto f = boost::bind(&foo, boost::placeholders::_1, std::string("A"));
f has the signature int f(MyStruct*)
and when called with
auto i = f(&mystruct);
it is equivalent to calling:
auto i = foo(&mystruct, std::string("A"));

How to use bind correctly here?

I can not figure out the correct syntax to bind member functions.
If I have a function that takes a function with a single argument,
how do I pass an object to it?
In the following example, what would be the correct syntax of passing the function?
#include <iostream>
#include <functional>
void caller(std::function<void(int)> f)
{
f(42);
}
class foo
{
public:
void f(int x)
{
std::cout<<x<<std::endl;
}
};
int main()
{
foo obj;
caller(std::bind(&foo::f,obj));
//^Wrong
}
Error was:
a.cpp: In function ‘int main()’:
a.cpp:18:34: error: could not convert ‘std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (foo::*)(int); _BoundArgs = {foo&}; typename std::_Bind_helper<std::__or_<std::is_integral<typename std::decay<_Tp>::type>, std::is_enum<typename std::decay<_Tp>::type> >::value, _Func, _BoundArgs ...>::type = std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo)>]((* & obj))’ from ‘std::_Bind_helper<false, void (foo::*)(int), foo&>::type {aka std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo)>}’ to ‘std::function<void(int)>’
caller(std::bind(&foo::f,obj));
Placeholders create a "space" for the actual arguments to be bound later:
int main()
{
foo obj;
caller(std::bind(&foo::f, &obj, std::placeholders::_1));
// ^ placeholder
// ^ address or even foo()
}
These placeholders are needed to correctly generate an appropriate signature for the std::bind result to be bound to the std::function<void(int)>.
You may also want to use the address of your object, or std::ref (so it won't be copied); this will vary on what you want the semantics to be.
There is an implicit first argument to member functions, which is the this point. You need to send it as a pointer; you also need a placeholder for the int argument. So:
caller(std::bind(&foo::f, &obj, std::placeholders::_1));
// ^ ^^^^^^^^^^^^^^^^^^^^^^^
You need to specify that the created function object takes a parameter using a placeholder:
std::bind(&foo::f,obj, std::placeholders::_1)