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 forstd::barrier. Maybe you wantstd::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.