#Compile Error Related to my Implementation of std::thread

23 messages · Page 1 of 1 (latest)

weak blade
#

Problem: I am attempting to create threads using std::thread and pass an int as a parm to the newly-formed thread. I am; however, getting a complex compiler error.
Expected Outcome: The program compiles without error so that I can create threads with the necessary parm.

Error:

See next post (exceeds post limit)

C++ (excerpt):

class Threading {
public:
  Threading();
  virtual ~Threading();
private:
  void ThreadWorkload(int &);
  std::vector<std::thread> threads;
};

//...
for(int _i = 0; _i < Configuration::numberOfThreads; _i++) {
  try {
    threads.emplace_back(std::thread(&Threading::ThreadWorkload, this, _i + 1));  //<-- Error occurs because of this line
//...

If someone could assist me, I would greatly appreciate it!

meager wigeonBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

weak blade
#

Error:

/usr/include/c++/13/bits/std_thread.h:157:72: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
  157 |                                       typename decay<_Args>::type...>::value,
      |                                                                        ^~~~~
/usr/include/c++/13/bits/std_thread.h:157:72: note: ‘std::integral_constant<bool, false>::value’ evaluates to false
/usr/include/c++/13/bits/std_thread.h: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> >’:
/usr/include/c++/13/bits/std_thread.h:236:13:   required from ‘struct std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> > >’
/usr/include/c++/13/bits/std_thread.h:164:29:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (MyNamespace::Threading::*)(int&); _Args = {MyNamespace::Threading*, int}; <template-parameter-1-3> = void]’
/usr/include/c++/13/bits/std_thread.h:291:11: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> >::__result<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> >’
  291 |           _M_invoke(_Index_tuple<_Ind...>)
      |           ^~~~~~~~~
/usr/include/c++/13/bits/std_thread.h:295:9: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> >::__result<std::tuple<void (MyNamespace::Threading::*)(int&), MyNamespace::Threading*, int> >’
  295 |         operator()()
      |         ^~~~~~~~
rustic light
#

it just makes no sense to try to pass _i + 1 into ThreadWorkload and that lack of sense isn't going to go away by using threads

#

;compile

class Threading {
public:
  Threading() {}
  virtual ~Threading();
//private:
  void ThreadWorkload(int &) {}
  //std::vector<std::thread> threads;
};

int main()
{
  Threading t;
  int _i = 0;
  t.ThreadWorkload(_i + 1);
}
mental chasmBOT
#
Compiler Output
<source>: In function 'int main()':
<source>:14:23: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
   14 |   t.ThreadWorkload(_i + 1);
      |                    ~~~^~~
<source>:6:23: note:   initializing argument 1 of 'void Threading::ThreadWorkload(int&)'
    6 |   void ThreadWorkload(int &) {}
      |                       ^~~~~
Build failed
rustic light
#

before worrying about using std::thread, you have to determine what the argument to ThreadWorkload should be and what meaning it has

#

using a int& means that the caller needs to see the changes that ThreadWorkload is going to make to make to the parameter, which means that it fundamentally makes no sense to try and pass a temporary object as argument

weak blade
# rustic light using a `int&` means that the *caller* needs to see the changes that `ThreadWork...

Hello @rustic light , thank you for your response!

I am trying to keep the threads ID'd and synced with the asynchronous io context handler of boost::asio::io_context. That is the reason I am trying to pass the value. I guess what I /could/ do is to spawn {x} number of threads, pass nothing to the threads, use mutex locking to ensure no race conditions, and then have them each read from and increment the value stored in the main thread. Essentially, self-assign themselves the ID.

meager wigeonBOT
#

@weak blade Has your question been resolved? If so, type !solved :)

weak blade
rustic light
#

If you just need to pass an integer ID there's absolutely no reason it has to be a reference

#

Unless for some ungodly reason the ID is mutable (and the thread needs to see the mutation), but if it was then it would raise questions as to why it can possibly work as an ID

#

The crux of the issue is that you decided to use a reference, and I don't get why with the little bit of context you've just provided

weak blade
rustic light
#

and not by reference

#
- void ThreadWorkload(int &);
+ void ThreadWorkload(int);
weak blade
weak blade
#

@rustic light : That fixed it, thank you! I really appreciate your assistance.

#

!solved