Non*_*yme 1 c++ arrays constructor raii
我有以下互斥体数组:
std::mutex mtx[5];
Run Code Online (Sandbox Code Playgroud)
我想用 RAII 风格锁定它们:
std::lock_guard<std::mutex> grd[5] { mtx[0], mtx[1], mtx[2], mtx[3], mtx[4] };
Run Code Online (Sandbox Code Playgroud)
虽然上面的代码可以工作,但它并不理想,因为我无法独立于数组的大小(此处为 5)来编写它。
有没有办法做到这一点?我应该使用模板魔法来创建一个std::initializer_list数组吗?(那可能吗?)
我愿意使用std::array或std::vector代替 C 风格的数组,为了简洁起见,我在这里使用了这些数组。理想情况下,这适用于 C++14,但任何符合最新标准的解决方案都可以。
你想要的是std::scoped_lock。它需要 N 个互斥体并在创建时锁定它们并在销毁时解锁它们。那会给你
std::scoped_lock sl{mtx[0], mtx[1], mtx[2], mtx[3], mtx[4]};
Run Code Online (Sandbox Code Playgroud)
如果这仍然太冗长,您可以将其包装在工厂函数中,例如
// function that actually creates the lock
template<typename Mutexes, std::size_t N, std::size_t... Is>
auto make_scoped_lock(Mutexes (&mutexes)[N], std::index_sequence<Is...>)
{
return std::scoped_lock{mutexes[Is]...};
}
// helper function so you don't have to create your own index_sequence
template<typename Mutexes, std::size_t N>
auto make_scoped_lock(Mutexes (&mutexes)[N])
{
return make_scoped_lock(mutexes, std::make_index_sequence<N>{});
}
int main()
{
std::mutex mtx[5];
auto lock = make_scoped_lock(mtx);
}
Run Code Online (Sandbox Code Playgroud)
如果您改用 astd::array来保存互斥体,那么代码可以简化为调用来std::apply将数组扩展为参数包,如下所示
template<typename Mutexes>
auto make_scoped_lock(Mutexes& mutexes)
{
return std::apply([](auto&... mutexes) { return std::scoped_lock{mutexes...}; },
mutexes);
}
int main()
{
std::array<std::mutex, 5> mtx;
auto sl = make_scoped_lock(mtx);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
589 次 |
| 最近记录: |