0

I'm currently looking at producing a C++ library. I've not much experience with C++ and have what is probably a very basic question about class instance method calling.

main.cpp

msgserver m;
std::thread t1(m.startServer, "192.168.50.128", 8081);

msgserver.h

class msgserver
{
public:    
    msgserver() { }
    int startServer(std::string addr, int port);
};

msgserver.cpp

int msgserver::startServer(string addr, int port)

This code results in:

[C3867] 'msgserver::startServer': non-standard syntax; use '&' to create a pointer to member

I know i can fix the compiler error by making this method static but I'm unsure if that is a requirement imposed by the fact it's being called in a thread constructor (which doesn't allow the parens on the call signature) or if I need to figure out the syntax.

I've read around this and it's actually left me a bit more confused that when I started. It seems any fix I apply like:

int &msgserver::startServer(string addr, int port)
or
std::thread t1(&m.startServer, "192.168.50.128", 8081);

Is actually illegal syntax according to the compiler.

How can I call this as an instance method? Or is actually a good idea to start a thread running in the background on a static function?

14
  • I'm not using any textbook. I'm guessing you're going to tell me that's my first mistake ... ;) Commented Jul 11, 2022 at 16:33
  • 2
    please show a minimal reproducible example Commented Jul 11, 2022 at 16:34
  • 2
    std::thread t1(&msgserver::startServer, m, "<ip>", 8081); Commented Jul 11, 2022 at 16:36
  • 3
    @Jammer I've got 25 years desktop dev behind me in other languages which helps -- One huge warning -- do not use any of those languages as a model in writing C++ code. If you use any of those languages as a model, you will wind up with 1) Buggy code, 2) Inefficient code, 3) Code that looks weird to a C++ programmer when trying to make C++ look like language <X>'s way of doing things. C++ has to be learned as if none of those other languages exist. For 3), I've seen int y = 10; string x = "" + y;, which looks ordinary to a Java programmer, but is totally wrong in C++ (concatenating). Commented Jul 11, 2022 at 16:39
  • 1
    @Jammer That's exactly what it does. You would be surprised how many Java programmers just do this, because that's what they're used to seeing. Now imagine a Java programmer trying to concatenate an int onto a string in C++, and they write that code. Then they can't understand why their C++ code doesn't work. But a C++ programmer looking at that same code would see it looks totally alien, weird, and just plain nuts. That is the perfect example of using another language as a model in writing C++ code, and totally failing. Commented Jul 11, 2022 at 19:43

2 Answers 2

3

The syntax for a getting a pointer to a member function is &<class name>::<function_name>.

In this case &msgserver::startServer would be the correct expression. Since std::invoke is used on the background thread, you need to pass the object to call the function for as second constructor parameter for std::thread, either wrapped in a std::reference_wrapper or by passing a pointer:

std::thread t1(&msgserver::startServer, std::ref(m), "192.168.50.128", 8081);

or

std::thread t1(&msgserver::startServer, &m, "192.168.50.128", 8081);
Sign up to request clarification or add additional context in comments.

Comments

1

Replace

msgserver m;
std::thread t1(m.startServer, "192.168.50.128", 8081);

with the lambda function

msgserver m;
std::thread t1([=](std::string addr, int port){ m.startServer(addr, port); }, 
    "192.168.50.128", 8081);

I'm guess that you expected your version to do what the lambda function does by some kind of C++ magic. But that's not how C++ works.

Completely endorse the recommendation that you get a C++ book. Now you have lambda functions to add to your list of topics to learn.

7 Comments

Ahhhh lambdas. Thank you. Will go study and test.
Missing a closing "}"
@Jammer Yes, fixed now
Ahhh, fixed. Fab. Thank you, will go check.
@Jammer This lambda function copies the msgserver object, that may or may not be a good idea. If not then replace [=] with [&] but then you have the new issue that the lifetime of your thread and the lifetime of your msgserver are no longer linked.
|

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.