Home > Enterprise >  C std::thread arguments must be invocable after conversion to rvalues
C std::thread arguments must be invocable after conversion to rvalues

Time:01-05

I'm clueless on whats going on here

here is a simple code example of what I'm trying to achieve:

main.cpp

#include <iostream>
#include <thread>

int main(int argc, char** argv) {

    constexpr int SIZE = 10;

    std::array<int, SIZE> arr{0};

    auto add = []<typename T>(std::array<T, SIZE>& arr) {
        for (int i = 0; i < SIZE; i  )
            arr[i] = i   1;
    };

    std::thread t1(std::ref(add), std::ref(arr));
    t1.join();

    return 0;
}

compile command:

g   -std=c  20 -Wall main.cpp -pthread -o t1

error:

In file included from /usr/include/c  /11.1.0/stop_token:35,
                 from /usr/include/c  /11.1.0/thread:40,
                 from main.cpp:2:
/usr/include/c  /11.1.0/bits/std_thread.h: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >; _Args = {std::reference_wrapper<std::array<int, 10> >}; <template-parameter-1-3> = void]’:
main.cpp:15:48:   required from here
/usr/include/c  /11.1.0/bits/std_thread.h:130:72: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
  130 |                                       typename decay<_Args>::type...>::value,
      |                                                                        ^~~~~
/usr/include/c  /11.1.0/bits/std_thread.h:130:72: note: ‘std::integral_constant<bool, false>::value’ evaluates to false
/usr/include/c  /11.1.0/bits/std_thread.h: In instantiation of ‘struct std::thread::_Invoker<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > >’:
/usr/include/c  /11.1.0/bits/std_thread.h:203:13:   required from ‘struct std::thread::_State_impl<std::thread::_Invoker<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > > >’
/usr/include/c  /11.1.0/bits/std_thread.h:143:29:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >; _Args = {std::reference_wrapper<std::array<int, 10> >}; <template-parameter-1-3> = void]’
main.cpp:15:48:   required from here
/usr/include/c  /11.1.0/bits/std_thread.h:252:11: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > >::__result<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > >’
  252 |           _M_invoke(_Index_tuple<_Ind...>)
      |           ^~~~~~~~~
/usr/include/c  /11.1.0/bits/std_thread.h:256:9: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > >::__result<std::tuple<std::reference_wrapper<main(int, char**)::<lambda(std::array<T, 10>&)> >, std::reference_wrapper<std::array<int, 10> > > >’
  256 |         operator()()
      |         ^~~~~~~~

note:

if I change the lambda to:

auto add = []<typename T>(std::array<T, SIZE> arr)

and call the thread like this:

std::thread t1(std::ref(add), arr);

it compiles, but obviously the array doesn't changed because its a copy and not a reference

CodePudding user response:

std::reference_wrapper is not a std::array, so T cannot be deduced.

add(std::ref(arr)); doesn't compile neither.

You might use

std::thread t1([&](auto arg){ add(arg.get()); }, std::ref(arr));

Demo

  •  Tags:  
  • Related