C++ - compilation fails on calling overloaded function in std::thread - c++

Consider the following scenario:
// utils.h
#include <string>
#include <list>
namespace Utils {
void do_something(int a, std::list<int> *b);
void do_something(int a, std::list<std::string> *b);
};
// utils.cpp
#include "utils.h"
void Utils::do_something(int a, std::list<int> *b) {
}
void Utils::do_something(int a, std::list<std::string> *b) {
}
// main.cpp
#include <thread>
#include <list>
#include "utils.h"
int main() {
std::list<int> list;
std::thread t(Utils::do_something, 17, &list);
t.join();
return 0;
}
When I compile it, I get the following error:
error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, int, std::list<int>*)'
Any idea what I'm doing wrong? Before I added the overloading function that gets std::list<std::string>*, it did compile well.

The issue here is even though you pass the parameters to std::thread it does not use those to try and determine the function passed to it. It tries to resolve the function type in isolation. When it does so, it sees there are two different versions and so it stops, as it does not know which one you want.
Unfortunately You are going to have to tell the compiler which function you want to use. You can do that by casting the function to the specific function pointer you want.
Instead of doing that though you can use a lambda to make this easy by allowing overload resolution to take place in a regular function call like
std::thread t([](auto first, auto second){ return Utils::do_something(first, second); }, 17, &list);
This will also work well with member functions as you just capture the object to call the function on with the capture list of the lambda. That saves you from having to pass that object to std::thread or using std::bind.

You can use a static_cast to disambiguate the overloads...
std::thread t(static_cast<void(*)(int, std::list<int> *)>(&Utils::do_something), 17, &list);

Related

How to bind a static member function to a boost::function using boost::bind

I want to bind a static member function to a boost::function using boost::bind. The following is an example of what I want to do (not working).
class Foo {
public:
static void DoStuff(int param)
{
// To do when calling back
}
};
class Question {
public:
void Setup()
{
AssignCallback(boost::bind(&Foo::DoStuff, _1)); // How to bind the static funciton here
}
void AssignCallback(boost::function<void(int param)> doStuffHandler)
{
...
...
}
};
I have previously used boost::bind with member functions using this syntax:
boost::bind(&Foo::NonStaticMember, this, _1, _2, _3, _4)
But this is obviously not correct for a static member.
Can you please explain to me how to correctly bind a static member function of a class using boost::bind?
It will be done as you do for normal functions binding.
For static function you just need to use its class name for to recognize the function by the compiler and skip the this argument since static finctions are bound to class not to the object.
Below is a simple example:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
void test(boost::function<bool(int, int)> func)
{
std::cout<<"in test().\n";
bool ret = func(10, 20);
std::cout<<"Ret:"<<ret<<"\n";
}
class Test
{
public:
static bool test2(int a, int b)
{
std::cout<<"in test2().\n";
return a>b;
}
};
int main()
{
test(boost::bind(&Test::test2, _1, _2));
return 0;
}
O/P:
in test().
in test2().
Ret:0
You should not use this as static functions dont have this pointer.
int main()
{
test(boost::bind(&Test::test2, this, _1, _2));-----> Illegal
return 0;
}
Below error will occur:
techie#gateway1:myExperiments$ g++ boost_bind.cpp
boost_bind.cpp: In function âint main()â:
boost_bind.cpp:26: error: invalid use of âthisâ in non-member function
Hope this will help. :-)
Your code is correct. Maybe you experience some compiler issue? Can you cite the compilation output?
You can also try using std::function and std::bind instead. Only replace boost headers with "functional" header and write
std::placeholders::_1
instead of
_1

Using erase-remove idiom for function<void()>

Stacked people.
Iam trying to implement an observer(esque?) pattern for my program. I have a component which stores what functions should be called if an event occours. My prolem is that i dont know how should i erase my function from the container, if the need arises. Tried storing the functions by reference, but iam not sure how to do that(or if thats possible.)
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
enum class EVENT_TYPE{
anEvent
};
class EventableComponent{
map<EVENT_TYPE, vector<function<void()>>> listeners;
public:
void trigger(EVENT_TYPE _et){
for(auto& it : listeners[_et]){
it();
}
}
void registerListener(EVENT_TYPE _et, function<void()> _fn){
listeners[_et].push_back(_fn);
};
void removeListener(EVENT_TYPE _et, function<void()> _fn){
//error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::function<void (void)>'
//(or there is no acceptable conversion)
listeners[_et].erase(remove(listeners[_et].begin(), listeners[_et].end(), _fn), listeners[_et].end());
};
};
int main(){
EventableComponent ec;
// this would become a member function for a class somewhere down the line
auto fn = [](){cout << "Hello.\n"; };
ec.registerListener(EVENT_TYPE::anEvent, fn);
ec.trigger(EVENT_TYPE::anEvent);
ec.removeListener(EVENT_TYPE::anEvent, fn);
ec.trigger(EVENT_TYPE::anEvent);
cin.get();
return 0;
};
Your problem can be reduced to the fact that two std::function instances cannot be compared for equality. std::remove requires operator==, and std::function does not have it. See "Why is std::function not equality comparable?".
Consider the following situation.
Let's say you defined two lambdas in your main:
auto fn = [](){cout << "Hello.\n"; };
auto fn2 = [](){cout << "Hello.\n"; };
Now, are those two equal or not? They do the same thing, but perhaps this is sheer coincidence. Would they become unequal if the second "Hello" became "Hello2"? Would they become unequal if the second one was no longer a lambda but a real function void f()?
The thing is that there can be no generally useful definition of equality for function objects, so it's up to you to define what equality really means in the context of your program.
You have several options to solve the problem at hand. One would be to operate on pointers to std::function objects. Pointers can be compared, and proper use of std::unique_ptr makes sure that deallocation is handled correctly.
Or you assign an identifier to every std::function you use. See the following modified example of your code in which direct storage of std::function<void()> in the vector is replaced with a custom type EventFunction that maps an int to the function object. The example uses std::remove_if to compare only the ints:
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
enum class EVENT_TYPE{
anEvent
};
struct EventFunction {
function<void()> f;
int id;
};
class EventableComponent{
map<EVENT_TYPE, vector<EventFunction>> listeners;
public:
void trigger(EVENT_TYPE _et){
for(auto& it : listeners[_et]){
it.f();
}
}
void registerListener(EVENT_TYPE _et, EventFunction _fn){
listeners[_et].push_back(_fn);
};
void removeListener(EVENT_TYPE _et, int function_id){
//error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::function<void (void)>'
//(or there is no acceptable conversion)
listeners[_et].erase(remove_if(listeners[_et].begin(), listeners[_et].end(),
[&](EventFunction const& e) { return e.id == function_id; }), listeners[_et].end());
};
};
int main(){
EventableComponent ec;
// this would become a member function for a class somewhere down the line
auto fn = [](){cout << "Hello.\n"; };
ec.registerListener(EVENT_TYPE::anEvent, EventFunction{ fn, 1 });
ec.trigger(EVENT_TYPE::anEvent);
ec.removeListener(EVENT_TYPE::anEvent, 1);
ec.trigger(EVENT_TYPE::anEvent);
};
Tried storing the functions by reference, but iam not sure how to do
that(or if thats possible.)
It's not possible because you cannot store references in standard-library containers. But I suppose the idea is similar to the one with pointers I mentioned above.

function pointers using functions in an object with parameters

I have been playing around with function pointers in c++ and seem to have found a bit of a problem. I made a demo to reproduce the error in a simple example.
I have the header file
class MyClass
{
public:
void MyFunction(int i);
MyClass();
~MyClass();
};
and the cpp file
#include "MyClass.h"
#include <iostream>
#include <functional>
using namespace std;
MyClass::MyClass()
{
//doesn't work
function<void(int)> func = &MyClass::MyFunction;
}
void MyClass::MyFunction(int i)
{
cout << i << endl;
}
In the constructor of the cpp file I am trying to create a pointer to MyFunction. It gives the error error C2664: 'void std::_Func_class<_Ret,int>::_Set(std::_Func_base<_Ret,int> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,int> *' in the functional file at line 506. It works fine with a parameterless method, but not with them. Does anyone know why, and how to resolve it?
You can use this and bind the object being constructed to the function. For instance, if your constructor looked like this:
MyClass::MyClass()
{
function<void(int)> func = bind(&MyClass::MyFunction, this, placeholders::_1);
func(6);
}
And you created a MyClass instance:
MyClass instance;
Then 6 will be printed to stdout.
You can also use std::mem_fn in C++11, which wraps a member function/variable into a callable closure
#include <iostream>
#include <functional>
class MyClass
{
public:
MyClass()
{
auto func = std::mem_fn(&MyClass::MyFunction);
func(this, 42); // call it on the current instance
}
void MyFunction(int i)
{
std::cout << i << std::endl;
}
};
int main()
{
MyClass foo;
}
or, you can explicitly specify the instance you're calling the pointer to member function
MyClass()
{
auto func = &MyClass::MyFunction;
(this->*func)(42); // call it on the current instance
}
In particular, note that std::function<void(int)> is not convertible to a pointer to member function. See related Using generic std::function objects with member functions in one class
That's why using auto with std::mem_fn gets rid of all the pain.

How can I use a boost function to transform the parameter types?

I want to create a boost function object of the following signature:
void (int, boost::uuid);
However, I would like to bind it to a function of the following form:
void (SomeType, boost::uuid)
Where the SomeType argument comes from another function call, so that if I were to call it straight out it would look like:
SomeType myOtherFunction(int);//Prototype
...
myFunction(myOtherFunction(int), myUUID);
In other words, I want the top level function object to completely hide the concept of SomeType and the call to myOtherFunction from the user. Is there a way to do this with one or more boost::function objects created with boost::bind calls?
Functional composition: Live On Coliru
#include <boost/uuid/uuid.hpp>
struct SomeType {};
SomeType myOtherFunction(int) { return SomeType(); }
void foo(SomeType, boost::uuids::uuid) {}
#include <boost/bind.hpp>
#include <boost/function.hpp>
int main()
{
boost::function<void(int, boost::uuids::uuid)> composed;
composed = boost::bind(foo, boost::bind(myOtherFunction, _1), _2);
}
Anyways, in c++11 you'd write [](int i, uuid u) { return foo(myOtherFunction(i), u); } of course

How to use boost bind with a member function

The following code causes cl.exe to crash (MS VS2005).
I am trying to use boost bind to create a function to a calls a method of myclass:
#include "stdafx.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
class myclass {
public:
void fun1() { printf("fun1()\n"); }
void fun2(int i) { printf("fun2(%d)\n", i); }
void testit() {
boost::function<void ()> f1( boost::bind( &myclass::fun1, this ) );
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this ) ); //fails
f1();
f2(111);
}
};
int main(int argc, char* argv[]) {
myclass mc;
mc.testit();
return 0;
}
What am I doing wrong?
Use the following instead:
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this, _1 ) );
This forwards the first parameter passed to the function object to the function using place-holders - you have to tell Boost.Bind how to handle the parameters. With your expression it would try to interpret it as a member function taking no arguments.
See e.g. here or here for common usage patterns.
Note that VC8s cl.exe regularly crashes on Boost.Bind misuses - if in doubt use a test-case with gcc and you will probably get good hints like the template parameters Bind-internals were instantiated with if you read through the output.
Boost.Bind is a library that simplifies and generalizes capabilities that originally required std::bind1st() and std::bind2nd()
Example 1.1: std::for_each() with a compatible function
#include <vector>
#include <algorithm>
#include <iostream>
void print(int i)
{
std::cout << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), print);
}
The third parameter of std::for_each() is a function or function object that expects a sole parameter. In Example 1.1, std::for_each() passes the numbers in the container v as sole parameters, one after another, to print().
If you need to pass in a function whose signature doesn’t meet the requirements of an algorithm, it gets more difficult. For example, if you want print() to accept an output stream as an additional parameter, you can no longer use it as is with std::for_each().
Example 1.2. std::for_each() with std::bind1st()
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
class print : public std::binary_function<std::ostream*, int, void>
{
public:
void operator()(std::ostream *os, int i) const
{
*os << i << '\n';
}
};
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), std::bind1st(print{}, &std::cout));
}
Like Example 1.1, Example 1.2 writes all numbers in v to standard output. However, this time, the output stream is passed to print() as a parameter. To do this, the function print() is defined as a function object derived from std::binary_function.
With Boost.Bind, you don’t need to transform print() from a function to a function object. Instead, you use the function template boost::bind(), which is defined in boost/bind.hpp.
Example 1.3: std::for_each() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
void print(std::ostream *os, int i)
{
*os << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), boost::bind(print, &std::cout, _1));
}
Example 1.3 uses print() as a function, not as a function object. Because print() expects two parameters, the function can’t be passed directly to std::for_each(). Instead, boost::bind() is passed to std::for_each() and print() is passed as the first parameter to boost::bind().
Since print() expects two parameters, those two parameters must also be passed to boost::bind(). They are a pointer to std::cout and _1.
_1 is a placeholder. Boost.Bind defines placeholders from _1 to _9. These placeholders tell boost::bind() to return a function object that expects as many parameters as the placeholder with the greatest number. If, as in Example 1.3, only the placeholder _1 is used, boost::bind() returns a unary function object – a function object that expects a sole parameter. This is required in this case since std::for_each() passes only one parameter.
std::for_each() calls a unary function object. The value passed to the function object – a number from the container v – takes the position of the placeholder _1. boost::bind() takes the number and the pointer to std::cout and forwards them to print().
Please note that boost::bind(), like std::bind1st() and std::bind2nd(), takes parameters by value. To prevent the calling program from trying to copy std::cout, print() expects a pointer to a stream. Boost.Ref provides a function which allows you to pass a parameter by reference.
Example 1.4 illustrates how to define a binary function object with boost::bind(). It uses the algorithm std::sort(), which expects a binary function as its third parameter.
Example 1.4. std::sort() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2));
for (int i : v)
std::cout << i << '\n';
}
In Example 1.4, a binary function object is created because the placeholder _2 is used. The algorithm std::sort() calls this binary function object with two values from the container v and evaluates the return value to sort the container. The function compare() is defined to sort v in descending order.
Since compare() is a binary function, it can be passed to std::sort() directly. However, it can still make sense to use boost::bind() because it lets you change the order of the parameters. For example, you can use boost::bind() if you want to sort the container in ascending order but don’t want to change compare()
Example 1.5. std::sort() with boost::bind() and changed order of placeholders
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));
for (int i : v)
std::cout << i << '\n';
}
The following works for me.
class test_component
{
private:
void on_wait_complete(const int i);
};
void test_component::on_wait_complete (const int i)
{
cout << "on_wait_complete was called" << endl;
return;
}
int main()
{
// timerPtr_ is a variable declared in class test_component.
timerPtr_->async_wait(boost::bind(&test_component::on_wait_complete, this, _1));
}