7

From what I have looked up, my syntax is correct but my compiler (VS2015) is complaining. Note, I'm using namespace ee with the class Network. Here's the code

    //code that doens't work
    thread clientThread(&ee::Network::clientRun, new ee::Network);

*note: in the real code I'm not calling new as an argument, I did it here to shorten code.

I've tested the functions and they work, I just can't get them to work using thread. Here is their signatures.

    void serverRun();
    void clientRun();
    void clientRun(string ip);

My errors are:

  1. Error C2661 'std::thread::thread': no overloaded function takes 2 arguments

  2. abc no instance of constructor "std::thread::thread" matches the argument list

Does anyone have any insight as to what might be happening in this situation?

Enigma22134
  • 532
  • 5
  • 12
  • 1
    Perhaps a not-so-silly question, you included ``, right ? We don't have much to work with here. – WhozCraig Aug 05 '16 at 16:59
  • 1
    That looks like a Visual C++ error code -- what version are you using? – Ben Voigt Aug 05 '16 at 16:59
  • 6
    Also, you have an ambiguity problem. Try `void (ee::Network::*threadProc)() = &ee::Network::clientRun; thread clientThread(threadProc, new ee::Network);` – Ben Voigt Aug 05 '16 at 17:01
  • Craig, #include is included. 2. Visual C++ 2015 ben, about to try your suggestion – Enigma22134 Aug 05 '16 at 17:06
  • 1
    @MattStone I can see how that solved your problem (props to Ben), but that error messaging is just plain odd imho for the ambiguity of `clientRun` in your thread creation context. – WhozCraig Aug 05 '16 at 17:24
  • 1
    My compiler similarly gives `no instance of constructor std::thread::thread matches the argument list` but it goes on to list the argument types as `(, ee:Network *)` which suggests the ambiguity problem. – A.E. Drew Aug 05 '16 at 17:26
  • 2
    For explanation of why Ben's fix works and some other solution techniques, see: http://stackoverflow.com/questions/35984788/c-member-function-overloading-with-ampersand – A.E. Drew Aug 05 '16 at 17:28
  • Thanks, I accidentally deleted my comment where I said: "ben's solution fixed my problem but I don't understand why it is an ambiguity problem". Thank you for the responses guys. :) – Enigma22134 Aug 05 '16 at 17:31

1 Answers1

7

Ben's suggestion fixed my problem, but I'm not sure why.

The problem is with the first argument &ee::Network::clientRun. clientRun has 2 overloads, but at the point of template deduction (to deduce the types of the arguments to std::thread::thread<>) the compiler is not yet in a position to distinguish which of the overloads is more valid.

Ben's solution worked because the cast prior to the call has done the compilers' work for it - by specifying the type of Network::clientRun to be void (ee::Network*)(void) rather than the equally valid void (ee::Network*)(string).

Some examples:

#include <thread>
#include <string>

struct Network
{
  void clientRun();
  void clientRun(std::string);
};

int main()
{
  // not ok...
//  std::thread clientThread(&Network::clientRun, new Network);

  // ok - tells the compiler which overload
  auto member_function = static_cast<void (Network::*)()>(&Network::clientRun);
  std::thread clientThreadA(member_function, new Network);

  // also ok
  using call_type = void (Network::*)();
  std::thread clientThreadB(call_type(&Network::clientRun), new Network);
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142