问题与原因
在 C++20 中,C++添加了一个叫 std::barrier
的一个类模板,它可以用来提供提供一种线程协调机制,阻塞已知大小的线程组直至该组中的所有线程到达该屏障。1
但是在类中创建一个 barrier
的话会遇到一下问题(Visrual Studio 版本:17.9.4):
E0441 缺少 类模板 “std::barrier” 的参数列表
这是因为 std::barrier
是一个模板类,而不是一个具体的类。当你试图创建一个模板类的实例时,你需要提供模板参数。所以我们需要一个模板参数。类比一下,相当于类里面只声明的是 std::vector
而不是 std::vector<int>
。
解决
根据 cppreference 中所述,模板参数必须满足以下条件:
CompletionFunction must meet the requirements of MoveConstructible and Destructible.
std::is_nothrow_invocable_v<CompletionFunction&>
must be true. 1
第一行表示这个模板参数必须满足可移动构造和可析构,第二行表示这个模板参数不会抛出异常。
根据以上所述,本人提供的模板参数为 void(*)()noexcept
。使用这个模板参数原因如下:
- 因为
std::barrier
在期待计数抵达零时,需要调用我们提供的方法以更新状态,所以我们需要一个方法来更新状态; - 这个方法不需要任何参数和返回值,因为不需要,当
std::barrier
在期待计数抵达零时,会自动的调用这个方法,完成后重新计数; - 我们需要这个方法不会抛出异常,所以所以需要
noexpection
。
当然亦可以使用 std::_No_completion_function
,这意味着,当 std::barrier
在期待计数抵达零时,不会执行任何函数,也无法执行任何函数,直接重新计数。
补充
如果向 std::barrier
提供的方法为成员函数,将会出现没有与模板匹配的构造函数。这时请将这个成员方法修改为静态成员函数即可。