std::barrier is_nothrow_invocable_v<CompletionFunction&> shall be true 错误
std::barrier is_nothrow_invocable_v<CompletionFunction&> shall be true error
我正在尝试模拟一个掷骰子程序,更具体地说,获得同时获得n个骰子所需的掷骰数为6。
所以这是 fork-join 模型的教科书示例,目的是同时模拟滚动,然后在每次迭代后检查结果。
#include <iostream>
#include <vector>
#include <thread>
#include <random>
#include <array>
#include <barrier>
auto random_int(int min, int max)
{
static thread_local auto engine = std::default_random_engine{ std::random_device{}() };
auto dist = std::uniform_int_distribution<>(min, max);
return dist(engine);
}
int main()
{
constexpr auto n = 5;
auto done = false;
auto dice = std::array<int, n>{};
auto threads = std::vector<std::thread>{};
auto n_turns = 0;
auto check_result = [&]
{
++n_turns;
auto is_six = [](int i) {return 6 == i; };
done = std::all_of(std::begin(dice), std::end(dice), is_six);
};
auto bar = std::barrier{ n,check_result };
for (int i = 0; i < n; ++i)
{
threads.emplace_back([&, i]{
while (!done)
{
dice[i] = random_int(1, 6);
bar.arrive_and_wait();
}});
}
for (auto&& t : threads)
{
t.join();
}
std::cout << n_turns << std::endl;
}
我收到以下错误:
error C2338: N4861 [thread.barrier.class]/5:
is_nothrow_invocable_v<CompletionFunction&> shall be true
1>C:\Users\eduar\source\repos\C++20\C++20\main.cpp(114): message : see
reference to class template instantiation
'std::barriermain::<lambda_1>' being compiled
有人可以提示我做错了什么以及如何解决这个问题吗?
问题出在错误消息中。这很好,甚至引用了标准中有此要求的部分:[thread.barrier.class]/5:
CompletionFunction
shall meet the Cpp17MoveConstructible
(Table 28) and Cpp17Destructible
(Table 32) requirements.
is_nothrow_invocable_v<CompletionFunction&>
shall be true
.
您目前缺少最后一部分:您的 lambda 不是 nothrow-invocable。这是一个简单的解决方法:
auto check_result = [&]() noexcept
// ^~~~~~~~
{
++n_turns;
auto is_six = [](int i) {return i == 6; };
done = std::all_of(std::begin(dice), std::end(dice), is_six);
};
我也借机翻了你的Yoda条件,因为没有理由写Yoda条件。
我正在尝试模拟一个掷骰子程序,更具体地说,获得同时获得n个骰子所需的掷骰数为6。
所以这是 fork-join 模型的教科书示例,目的是同时模拟滚动,然后在每次迭代后检查结果。
#include <iostream>
#include <vector>
#include <thread>
#include <random>
#include <array>
#include <barrier>
auto random_int(int min, int max)
{
static thread_local auto engine = std::default_random_engine{ std::random_device{}() };
auto dist = std::uniform_int_distribution<>(min, max);
return dist(engine);
}
int main()
{
constexpr auto n = 5;
auto done = false;
auto dice = std::array<int, n>{};
auto threads = std::vector<std::thread>{};
auto n_turns = 0;
auto check_result = [&]
{
++n_turns;
auto is_six = [](int i) {return 6 == i; };
done = std::all_of(std::begin(dice), std::end(dice), is_six);
};
auto bar = std::barrier{ n,check_result };
for (int i = 0; i < n; ++i)
{
threads.emplace_back([&, i]{
while (!done)
{
dice[i] = random_int(1, 6);
bar.arrive_and_wait();
}});
}
for (auto&& t : threads)
{
t.join();
}
std::cout << n_turns << std::endl;
}
我收到以下错误:
error C2338: N4861 [thread.barrier.class]/5: is_nothrow_invocable_v<CompletionFunction&> shall be true 1>C:\Users\eduar\source\repos\C++20\C++20\main.cpp(114): message : see reference to class template instantiation 'std::barriermain::<lambda_1>' being compiled
有人可以提示我做错了什么以及如何解决这个问题吗?
问题出在错误消息中。这很好,甚至引用了标准中有此要求的部分:[thread.barrier.class]/5:
CompletionFunction
shall meet theCpp17MoveConstructible
(Table 28) andCpp17Destructible
(Table 32) requirements.is_nothrow_invocable_v<CompletionFunction&>
shall betrue
.
您目前缺少最后一部分:您的 lambda 不是 nothrow-invocable。这是一个简单的解决方法:
auto check_result = [&]() noexcept
// ^~~~~~~~
{
++n_turns;
auto is_six = [](int i) {return i == 6; };
done = std::all_of(std::begin(dice), std::end(dice), is_six);
};
我也借机翻了你的Yoda条件,因为没有理由写Yoda条件。