Because I can't use directly std::barrier in a class, I decided to use std::unique_ptr
in order to dynamically allocate it. That will also allow me to dynamically change the expected
number of thread.
Here is a sample snippet of my class.
class MyClass
{
public:
MyClass()
: la_barriere( std::make_unique< std::barrier<void()> >( 3, [this](){
callback1();callback2();
} ) )
{ /*empty constructor*/}
void run(){ la_barriere->arrive_and_wait(); }
private:
void callback1(){ std::cout << "callback1()\n"; }
void callback2(){ std::cout << "callback2()\n"; }
std::unique_ptr< std::barrier<void()> > la_barriere;
};
int main()
{
MyClass test;
std::jthread t1( &MyClass::run, &test );
std::jthread t2( &MyClass::run, &test );
std::jthread t3( &MyClass::run, &test );
return 0;
}
I getting these errors when I try to compile:
g++.exe -Wall -fexceptions -g -std=c++20 -c D:\Programmes\barrier_completion_function\main.cpp -o obj\Debug\main.o
g++.exe -o bin\Debug\barrier_completion_function.exe obj\Debug\main.o
In file included from D:\Programmes\barrier_completion_function\main.cpp:3:
C:/MinGW/include/c++/13.1.0/barrier: In instantiation of 'class std::__tree_barrier<void()>':
C:/MinGW/include/c++/13.1.0/barrier:216:21: required from 'class std::barrier<void()>'
D:\Programmes\barrier_completion_function\main.cpp:15:28: required from here
C:/MinGW/include/c++/13.1.0/barrier:99:20: error: data member 'std::__tree_barrier<void()>::_M_completion' invalidly declared function type
99 | _CompletionF _M_completion;
| ^~~~~~~~~~~~~
In file included from C:/MinGW/include/c++/13.1.0/bits/std_thread.h:43,
from C:/MinGW/include/c++/13.1.0/barrier:48:
C:/MinGW/include/c++/13.1.0/bits/unique_ptr.h: In instantiation of 'std::__detail::__unique_ptr_t<_Tp> std::make_unique(_Args&& ...) [with _Tp = barrier<void()>; _Args = {int, MyClass::MyClass()::<lambda()>}; __detail::__unique_ptr_t<_Tp> = __detail::__unique_ptr_t<barrier<void()> >]':
D:\Programmes\barrier_completion_function\main.cpp:10:60: required from here
C:/MinGW/include/c++/13.1.0/bits/unique_ptr.h:1070:30: error: no matching function for call to 'std::barrier<void()>::barrier(int, MyClass::MyClass()::<lambda()>)'
1070 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/MinGW/include/c++/13.1.0/barrier:238:7: note: candidate: 'std::barrier<_CompletionF>::barrier(std::ptrdiff_t, _CompletionF) [with _CompletionF = void(); std::ptrdiff_t = long long int]'
238 | barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
| ^~~~~~~
C:/MinGW/include/c++/13.1.0/barrier:238:47: note: no known conversion for argument 2 from 'MyClass::MyClass()::<lambda()>' to 'void (*)()'
238 | barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I want to allocate std::barrier
on the heap, dynamically change the expected
thread that must wait and the supplied completionFunction
being called after the each phase
This has nothing to do with the use of std::unique_ptr
.
The problem is that void()
is not a valid template argument for std::barrier
. Maybe you want std::barrier<std::function<void()>>
instead.
The template argument must be a function object type that is move-constructible and destructible, which function types like void()
are not.