0
votes

I am very frustrated that this is not working. I read most of the stackoverflow comments and examples and none of it shown to work. I just started doing c++.

I want the code to print "Hello World".

Here's a sample of my code (I can give my full code but I will be unnecessary since there is a lot of code in it):

#include <iostream>
#include <thread>

using namespace std;

class Greeting {
    public:
        void hi() {
           cout << "Hello World!\n";
        }
};

int main() {

Greeting g;

thread t(g.hi);
t.join();

return 0;
}

Error:

||=== Build: Debug in Cookie Island (compiler: GNU GCC Compiler) ===|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
||In instantiation of 'struct std::_Bind_check_arity<void (Greeting::*)()>':|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
|1538|required from 'struct std::_Bind_simple_helper<void (Greeting::*)()>'|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
|1552|  required by substitution of 'template<class _Callable, class ... _Args> 
typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type 
std::__bind_simple(_Callable&&, _Args&& ...) 
[with _Callable = void (Greeting::*)(); _Args = {}]'|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread
|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) 
[with _Callable = void (Greeting::*)(); _Args = {}]'|
C:\Users\Andrew Shen\Desktop\Cookie Island\main.cpp|51|required from here|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
|1426|error: static assertion failed: Wrong number of arguments for pointer-to-member|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
||In instantiation of 'struct std::_Bind_simple<std::_Mem_fn<void (Greeting::*)()>()>':|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread
|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) 
[with _Callable = void (Greeting::*)(); _Args = {}]'|
C:\Users\Andrew Shen\Desktop\Cookie Island\main.cpp|51|required from here|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
|1505|error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Greeting::*)()>()>'|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional
|1526|error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Greeting::*)()>()>'|
||=== Build failed: 4 error(s), 7 warning(s) (0 minute(s), 1 second(s)) ===|

Update: This is more like my code.

#include <iostream>
#include <thread>
#include <string>

using namespace std;

class Greeting {
    public:
        void hi(string txt) {
           cout << "Hello World!"+txt << endl;
        }
};

int main() {
string t = " More...";

Greeting g;

thread t(g.hi, &g, t);
t.join();

return 0;
}

Blockquote ||=== Build: Debug in Cookie Island (compiler: GNU GCC Compiler) ===| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional||In instantiation of 'struct std::_Bind_simple)>(Greeting*, std::__cxx11::basic_string*)>':| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Greeting::)(std::__cxx11::basic_string); _Args = {Greeting, std::__cxx11::basic_string, std::allocator >*}]'| C:\Users\Andrew Shen\Desktop\Cookie Island\main.cpp|52|required from here| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1505|error: no type named 'type' in 'class std::result_of)>(Greeting*, std::__cxx11::basic_string*)>'| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1526|error: no type named 'type' in 'class std::result_of)>(Greeting*, std::__cxx11::basic_string*)>'| ||=== Build failed: 2 error(s), 3 warning(s) (0 minute(s), 1 second(s)) ===|

2
One quick solution: Don't use a member function, use a lambda that calls your member function. - druckermanly
@druckermanly How are you suppose to do lambda. More specifically in this type of situation. - entropy32
Really anything would be easier here than the non-static member function you have. These need extra work because they require a hidden extra argument (the this pointer to the instance you're invoking the function on). A simple free function will be fine, since you have no instance data in Greeting anyway. - Useless
Notably you can't just pass the implicit this pointer as an explicit argument, as you tried. A lambda like [&](std::string s) { g.hi(s); } (replacing the first two arguments to the thread constructor) is the simplest way to get your current scheme working. - Useless
I said part of my code above. Meaning my full code actually has an instances. - entropy32

2 Answers

0
votes

Member functions are not part of objects but class. You need full qualified function name. You need to do following:

thread t(&Greeting::hi, &g, str);

Also, you accidentally used 't' as name of staring variable and for the thread, which i modified to str for string.

0
votes

Anyone of the following works,

string str = " More...";

thread t(Greeting::hi, g, str);

or,

thread t(&Greeting::hi, g, str);

or,

thread t(Greeting::hi, &g, str);

or,

thread t(&Greeting::hi, &g, str);

Can you explain the difference among all those situations, Please. @Abhinav