Является ли доступ к захваченному i
поточно-ориентированным?
Нет.Клиентский код несет ответственность за то, чтобы не происходили гонки данных.Вы можете сделать следующее (скопировать и настроить из cppreference )
int i = 0;
std::mutex m;
std::generate_n(std::execution::par, v.data(), v.size(), [&]() {
std::lock_guard<std::mutex> guard(m);
return i++; });
или, если вы настаиваете на лямбда-захвате вместе с ключевым словом mutable
:
std::generate_n(std::execution::par, v.data(), v.size(),
[i = 0, m = std::mutex()] () mutable {
std::lock_guard<std::mutex> guard(m);
return i++; });
Обратите внимание, что, как указал @Eric в комментариях, а @DmitryGordon в своем ответе, std::generate_n
может скопировать объект функции.Это проблематично, поскольку каждый скопированный экземпляр имеет свой собственный счетчик i
, который увеличивается независимо от других.Также обратите внимание, что @rubenvb указал, что копии объекта функции в std::generate_n
даже не должны компилироваться.Следовательно, первый пример явно предпочтителен и, возможно, даже единственный выполнимый.