2

Can someone please help me with the error I get when I create the thread in main, below?

#include "lock_free_queue.h"
#include "Consumer.h"
#include <thread>

int main(){
    lock_free_queue* my_queue = new lock_free_queue();
    Consumer* c = new Consumer(my_queue);

    //Error occurs here I think
    std::thread t3(&Consumer::start);
    ...
    t3.join();

Consumer.h (its all in the header because originally was going to use templates):

#ifndef CONSUMER_H
#define CONSUMER_H

#include "lock_free_queue.h"
#include <iostream>

class Consumer{
public:

    Consumer(lock_free_queue* queue) : the_queue(queue){}

    void start(){
        consume = true;
        while(consume){
            while(the_queue->getSize()==0){}
            process();
        }
    }

I get this error (rather scary-looking):

1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(1152): error C2064: term does not evaluate to a function taking 0 arguments
1>          class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(1152) : while compiling class template member function 'void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()(void)'
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__cdecl Consumer::* )(void),void,Consumer,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Nil,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\thr/xthread(195) : see reference to function template instantiation 'void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()(void)' being compiled
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__cdecl Consumer::* )(void),void,Consumer,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Nil,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\thread(52) : see reference to class template instantiation 'std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' being compiled
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__cdecl Consumer::* )(void),void,Consumer,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Nil,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil
1>          ]
1>          Main.cpp(10) : see reference to function template instantiation 'std::thread::thread<void(__cdecl Consumer::* )(void)>(_Fn)' being compiled
1>          with
1>          [
1>              _Fn=void (__cdecl Consumer::* )(void)
1>          ]

1 Answer 1

6

Consumer::start is a non-static member function. This means it needs an instance of Consumer to act on. Formally, this is done by giving non-static member functions an implicit first parameter for this. std::thread expects you to pass something that it can use as argument for this first parameter.

So, you need to pass a Consumer instance or a pointer to an instance, for the member function to act on:

std::thread t3(&Consumer::start, c);
Sign up to request clarification or add additional context in comments.

4 Comments

reference_wrapper is NOT specified to work in this case except with std::bind. See this question, and/or LWG issue 2219.
Sorry! I was using an old example I wrote and I was thinking the argument was for the function call, not the instance of the class :)
@Casey I think it is.
@Casey Interesting. So Wakely seems to be of the opinion that it should work. Thanks for the information. I will edit this post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.