I ran into a compiler error when I tried to execute a function using std::thread. The error says : "error C2672: 'std::invoke': no matching overloaded function found".
Here is a code snippet:
void GetMinMax_X(const std::vector<Vertex>& iAllVertices, double & oMin_X,
double & oMax_X)
{
auto MinMax_X = std::minmax_element(iAllVertices.begin(),
iAllVertices.end(), [](const Vertex& i, const Vertex& j)
{
return i.GetX() < j.GetX();
});
oMin_X = MinMax_X.first->GetX();
oMax_X = MinMax_X.second->GetX();
}
int main()
{
std::vector<Vertex>;
// Some functions to fill the Vertex vector......
double Min_X = 0;
double Max_X = 0;
std::thread first (GetMinMax_X, AllVertices, Min_X, Max_X);
first.join();
return 0;
}
Thanks!
The error comes up because std::thread uses std::invoke behind the scenes to invoke GetMinMax_X, but with the arguments copied/moved. In particular, you cannot use
void GetMinMax_X(const std::vector<int>& iAllVertices, double & oMin_X, double & oMax_X)
because you would be forming references to the copies, which is not what you want.
You could still use
void GetMinMax_X(const std::vector<int>& iAllVertices, const double & oMin_X, const double & oMax_X)
but that would not help you get back the values into the main thread.
The solution is to use std::ref:
std::thread first(GetMinMax_X, AllVertices, std::ref(Min_X), std::ref(Max_X));
https://godbolt.org/z/ClK3Cb
See also what cppreference has to say about std::thread (where this "limitation" and the workaround are described):
https://en.cppreference.com/w/cpp/thread/thread/thread
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).
Any return value from the function is ignored. If the function throws an exception, std::terminate is called. In order to pass return values or exceptions back to the calling thread, std::promise or std::async may be used.
Related
First of all, I want to say that i already made researches on the subject, but nothing relevant...
(Error creating std::thread on Mac OS X with clang: "attempt to use a deleted function")
(Xcode 7: C++ threads ERROR: Attempting to use a deleted function)
(xcode - "attempt to use a deleted function" - what does that mean?)
And here's my issue...:
clang error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:347:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
And that's my code:
bool GenAI::loadAIs()
{
bool ret = true;
if (_nbThread > 1)
{
std::vector<std::thread> threads;
for (unsigned int i = 0; i < _nbThread; ++i)
threads.push_back(std::thread(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs), this, ret, i));
for (unsigned int i = 0; i < _nbThread; ++i)
threads[i].join();
}
else
loadAIs(ret, 0);
return ret;
}
// And the prototype of the function that i try to call
void GenAI::loadAIs(bool & ret, unsigned int iThread);
If some one could help me that'd be really helpful ! :)
Regards ;)
To pass reference to thread, you have to use std::reference_wrapper, that you can obtain with std::ref. So your code becomes:
threads.emplace_back(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs),
this,
std::ref(ret),
i));
Note:
bool ret should probably be std::atomic<bool> ret, or should should have one bool by thread. Else you may have concurrent access on ret.
The deleted function that it is complaining about is a deleted copy constructor for const thread.
For the deleted function problem, you can use:
threads.emplace_back(
Instead of:
threads.push_back(
What the commenter also referred to is that the function is creating more than one thread and passing to them a reference to the same boolean return variable.
It will crash if you don't use atomic_bool and even if you do, they will all report back to the same memory location, making the function miss the notification if one of them returns false.
Source of Problem https://github.com/claydonkey/PointerToMember/tree/master
Although touched on in How Can I Pass a Member Function to a Function Pointer?, I feel somewhat dissatisfied with the solutions provided, as I don't want to introduce a dependency on the Boost library.
Comparing std::function for member functions is a post that gets close to a solution but ultimately is less optimistic about the use of std::function in .
(it seems that member functions cannot be passed as function pointers)
The Problem:
A function simpleFunction which cannot be altered takes a callback pfunc:
typedef int (*FuncPtr_t)(void*, std::pair<int,int>&);
static int simpleFunction(FuncPtr_t pfunc, void *context, std::pair<int,int>& nos)
{
pfunc(context, nos);
}
This function is intended to callback the method memberFunction in class SimpleClass:
NB removed void from original post as it better represents a real world usage.* was int memberFunction(void*, std::pair<int,int>& nos)
class SimpleClass {
public:
int memberFunction(std::pair<int,int>& nos) { return nos.first + nos.second; }
};
I expected the following to work:
MemFuncPtr_t MemFunction = &SimpleClass::memberFunction;
simpleFunction(obj.*MemFunction, nos);
but obj.*MemFunction has a type: int (SimpleClass::)(std::pair<int,int>&)
and it needs to be: int (*)(std::pair<int,int>&)
(wheras (obj.*MemFunction) (nos); returns as expected)
I can create and pass a trampoline:
int functionToMemberFunction(void* context, std::pair<int,int> & nos) {
return static_cast<SimpleClass*>(context)->memberFunction(nos);
}
and pass it
simpleFunction(&functionToMemberFunction, &obj, nos);
but it compiles to around 40 instructions.
I can pass a lambda:
simpleFunction((FuncPtr_t)[](void* , std::pair<int,int> & nos) {
return nos.first + nos.second;
}, &obj, nos);
That's surprisingly well optimised but a bit ugly and syntactically cumbersome.
(NB Both and lambdas require C++11)
I can add a static member to SimpleClass:
class SimpleClass {
public:
int memberFunction(void*, std::pair<int,int>& nos) { return nos.first + nos.second; }
static int staticFunction(void*, std::pair<int,int> & nos) { return nos.first + nos.second; }
};
FuncPtr_t StaticMemFunction = &SimpleClass::staticFunction;
and pass it
simpleFunction(StaticMemFunction, nullptr, nos);
and that's just, well ... a static function inside a class.
I can use the <functional> header:
using namespace std::placeholders;
std::function<int(std::pair<int,int>&) > f_simpleFunc =
std::bind(&SimpleClass::memberFunction, obj, _1);
auto ptr_fun = f_simpleFunc.target<int (std::pair<int,int> & ) >();
and try and pass it...
simpleFunction(*ptr_fun, nos);
but ptr_fun reports null.
Looking at the x86 assembly - I am at a loss at how memory is addressed, calling a member function (there are an extra 5 instructions [3 mov, 1 lea and 1 add] over the StaticMemFunction call). I can only imagine that this is down to locating the class instance in memory and then the function within it.
All the suggestions have been useful and I think if I collate them all and return to the original problem, I may have a solution that works for me.
So I thought a solution would be derived from:
simpleFunction(([](void* context,std::pair<int, int> & nos) {
return nos.first + nos.second;
}), &obj, nos);
to become:
simpleFunction(([&](void* context,std::pair<int, int> & nos) {
obj.memberFunction(nos);
}), &obj, nos);
right?
error: cannot convert main()::<lambda(std::pair<int, int>&, void*)> to int (*)(std::pair<int, int>&, void*)
Lambdas that accept closures cannot be cast to a function pointer
The closure type for a lambda-expression with no lambda-capture has a
public non-virtual non-explicit const conversion function to pointer
to function having the same parameter and return types as the closure
type’s function call operator. The value returned by this conversion
function shall be the address of a function that, when invoked, has
the same effect as invoking the closure type’s function call operator.
This makes sense as function pointers carry no state and this is why simpleFunction was gifted with a context pointer void* context (like most callbacks!), which is in turn handled by pFunc- the function pointer. (The context being the SimpleObject instance obj whose member function we wish to delegate to.)
Ergo a good solution seems to be:
solution 1
simpleFunction(([](void* context, std::pair<int,int>& n) {
return static_cast<SimpleClass*>(context)->memberFunction(n);
}), &obj, nos);
NB If obj is moved from local -> global scope the lambda would not require the object to be passed in at all. but that changes the original problem.
Incredibly, if the member-function has no calls to the class within which it resides, it behaves as a static function, the lambda obviating the need for the class instance
solution 2
simpleFunction(([](void* context, std::pair<int,int>& n) {
return static_cast<SimpleClass*>(context)->memberFunction(n);
}), nullptr /* << HERE */, nos); //WILL WORK even though the context is null!
This works perfectly as a solution to the original question: the member function indeed does not rely on anything outside the function scope (is this expected C++ behaviour or a happy hack?).
In conclusion, in trying to compose a simple analogy to a real world problem I have been naive in my the original question and I really want all the functionality of a member-function so solution 1 seems more realistic.
I am little more savvy in distinguishing between member functions and c functions - I spose the clue was in the name member (of a class)
This was all part of a learning experience and the source code including move-semantics solutions is in the link in the original post.
Implement a simple trampoline with a lambda:
#include <iostream>
typedef int (*FuncPtr_t)(void*, int);
static int simpleFunction(FuncPtr_t pfunc, void *context, int nos)
{
return pfunc(context, nos);
}
struct A {
int i;
int pf(int nos) { std::cout << i << " nos = " << nos << "\n"; return i; }
};
int main() {
A a { 1234 };
// could combine the next two lines into one, I didn't.
auto trampoline = [](void *inst, int nos) { return ((A*)inst)->pf(nos); };
simpleFunction(trampoline, &a, 42);
}
http://ideone.com/74Xhes
I've modified it to consider the assembly:
typedef int (*FuncPtr_t)(void*, int);
static int simpleFunction(FuncPtr_t pfunc, void *context, int nos)
{
return pfunc(context, nos);
}
struct A {
int i;
int pf(int nos) { return nos + i; }
};
int f(A& a) {
auto trampoline = [](void *inst, int nos) { return ((A*)inst)->pf(nos); };
return simpleFunction(trampoline, &a, 42);
}
Compiled with -O3 we get:
f(A&):
movl (%rdi), %eax
addl $42, %eax
ret
https://godbolt.org/g/amDKu6
I.e. the compiler is able to eliminate the trampoline entirely.
std::function<> plus lambdas are a nice way to go. Just capture the this in the lambda, an do what you need. You don't event need to write a separate callback if what is being executed is small. Plus std::function is required to not need a heap allocation for lambda that only captures a single pointer.
class A {
std::function <void()> notify;
void someProcessingFunction () {
// do some work
if (notify != nullptr)
notify ();
}
};
class B {
void processNotification () {
// do something in response to notification
}
};
int main ()
{
A a;
B b;
a.notify = [&b] () { b.processNotification (); };
a.someProcessingFunction ();
}
The usual approach is to pass the object as your callback data, as you do in the first example. Any overhead is likely a consequence of the calling convention on your target (or perhaps too low a setting on your compiler's optimiser).
In these circumstances I use a fusion of your first two methods. That is, I create a trampoline, but make it a static function inside the class, to avoid clutter. It does not do what the member function does (as in your second example): it just calls the member function.
Don't worry about a handful of instructions in the calling process. If you ever do need to worry that much about clock cycles, use assembler.
I am new working with threads.. but I got the concept and have been playing with it in the last days.
But now I am trying to create a thread calling a bool function and passing a string as argument. The code is basically:
bool className::analyseData(const std::string& filename) {
...
return true;
}
bool className::equalise(...) {
...
const std::string filename0 = filenameBase + "_chip" + ss.str() + "_0";
std::thread analyse_dat0(analyseData, &filename0);
...
return true;
}
and then I call equalise from other place.
But when I try to compile it I get the following error:
SpidrEqualisation_multi_threading.cpp:140:50: error:
no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, const string&)
std::thread analyse_dat0(analyseData, filename0);`
Any idea about how I can fix that?
Many thanks for the help.
You don't want to pass a pointer to that thread function:
std::thread analyse_dat0(analyseData, filename0); // omit the &
// address of operator
Instead of using std::thread for this purpose why not use std::async and get the result as std::future ? That's much simpler, IMO.
Class c;
auto ft = std::async([&] { return c.analyseData("file.txt"); });
bool result = ft.get();
Remove the & from td::thread analyse_dat0(analyseData, &filename0); as you want a reference not a pointer in analyseData.
Also you need to provide an object as analyseData isn't static.
I came across a Youtube video on c++11 concurrency (part 3) and the following code, which compiles and generates correct result in the video.
However, I got a compile error of this code using Visual Studio 2012. The compiler complains about the argument type of toSin(list<double>&&). If I change the argument type to list<double>&, the code compiled.
My question is what is returned from move(list) in the _tmain(), is it a rvalue reference or just a reference?
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <list>
#include <algorithm>
using namespace std;
void toSin(list<double>&& list)
{
//this_thread::sleep_for(chrono::seconds(1));
for_each(list.begin(), list.end(), [](double & x)
{
x = sin(x);
});
for_each(list.begin(), list.end(), [](double & x)
{
int count = static_cast<int>(10*x+10.5);
for (int i=0; i<count; ++i)
{
cout.put('*');
}
cout << endl;
});
}
int _tmain(int argc, _TCHAR* argv[])
{
list<double> list;
const double pi = 3.1415926;
const double epsilon = 0.00000001;
for (double x = 0.0; x<2*pi+epsilon; x+=pi/16)
{
list.push_back(x);
}
thread th(&toSin, /*std::ref(list)*/std::move(list));
th.join();
return 0;
}
This appears to be a bug in MSVC2012. (and on quick inspection, MSVC2013 and MSVC2015)
thread does not use perfect forwarding directly, as storing a reference to data (temporary or not) in the originating thread and using it in the spawned thread would be extremely error prone and dangerous.
Instead, it copies each argument into decay_t<?>'s internal data.
The bug is that when it calls the worker function, it simply passes that internal copy to your procedure. Instead, it should move that internal data into the call.
This does not seem to be fixed in compiler version 19, which I think is MSVC2015 (did not double check), based off compiling your code over here
This is both due to the wording of the standard (it is supposed to invoke a decay_t<F> with decay_t<Ts>... -- which means rvalue binding, not lvalue binding), and because the local data stored in the thread will never be used again after the invocation of your procedure (so logically it should be treated as expiring data, not persistent data).
Here is a work around:
template<class F>
struct thread_rvalue_fix_wrapper {
F f;
template<class...Args>
auto operator()(Args&...args)
-> typename std::result_of<F(Args...)>::type
{
return std::move(f)( std::move(args)... );
}
};
template<class F>
thread_rvalue_fix_wrapper< typename std::decay<F>::type >
thread_rvalue_fix( F&& f ) { return {std::forward<F>(f)}; }
then
thread th(thread_rvalue_fix(&toSin), /*std::ref(list)*/std::move(list));
should work. (tested in MSVC2015 online compiler linked above) Based off personal experience, it should also work in MSVC2013. I don't know about MSVC2012.
What is returned from std::move is indeed an rvalue reference, but that doesn't matter because the thread constructor does not use perfect forwarding for its arguments. First it copies/moves them to storage owned by the new thread. Then, inside the new thread, the supplied function is called using the copies.
Since the copies are not temporary objects, this step won't bind to rvalue-reference parameters.
What the Standard says (30.3.1.2):
The new thread of execution executes
INVOKE( DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))... )
with the calls to
DECAY_COPY being evaluated in the constructing thread.
and
In several places in this Clause the operation DECAY_COPY(x) is used. All such uses mean call the function decay_copy(x) and use the result, where decay_copy is defined as follows:
template <class T> decay_t<T> decay_copy(T&& v)
{ return std::forward<T>(v); }
The value category is lost.
I am new to Boost.Threads and am trying to understand how to pass function arguments to the boost::thread_groups::create_thread() function. After reading some tutorials and the boost documentations, I understand that it is possible to simply pass the arguments to this function but I can't get this method to work.
The other method I read about is to use functors to bind the parameters to my function but that would create copies of the arguments and I strictly require that const references be passed since the arguments will be big matrices(this I plan to do by using boost::cref(Matrix) once I get this simple example to work).
Now, let's get down to the code:
void printPower(float b, float e)
{
cout<<b<<"\t"<<e<<"\t"<<pow(b,e)<<endl;
boost::this_thread::yield();
return;
}
void thr_main()
{
boost::progress_timer timer;
boost::thread_group threads;
for (float e=0.; e<20.; e++)
{
float b=2.;
threads.create_thread(&printPower,b,e);
}
threads.join_all();
cout << "Threads Done" << endl;
}
This doesn't compile with the following error:
mt.cc: In function âvoid thr_main()â:
mt.cc:46: error: no matching function for call to âboost::thread_group::create_thread(void (*)(float, float), float&, float&)â
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp: In member function âvoid boost::detail::thread_data<F>::run() [with F = void (*)(float, float)]â:
mt.cc:55: instantiated from here
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp:61: error: too few arguments to function
What am I doing wrong?
You can't pass arguments to boost::thread_group::create_thread() function, since it gets only one argument. You could use boost::bind:
threads.create_thread(boost::bind(printPower, boost::cref(b), boost::cref(e)));
# ^ to avoid copying, as you wanted
Or, if you don't want to use boost::bind, you could use boost::thread_group::add_thread() like this:
threads.add_thread(new boost::thread(printPower, b, e));
For more flexibility you can use:
-Lambda functions (C++11): What is a lambda expression in C++11?
threads.create_thread([&b,&e]{printPower(b,e);});
-Functors that store the arguments as const references.
struct PPFunc {
PPFunc(const float& b, const float& e) : mB(b), mE(e) {}
void operator()() { printPower(mB,mE); }
const float& mB;
const float& mE;
};
-std::bind (C++11) or boost::bind