我有一个函数,语句 foo
应该在 lock_guard
下执行,但只有当一个指向 mutex
对象的指针被提供给函数作为参数。否则 foo
不必由 lock_guard
保护。
我不能在 if
中使用 lock_guard
,因为当 if
阻塞时锁会立即释放结束。
所以,这段代码是胡说八道:
bar( std::mutex * optionalMutex = nullptr )
{
...
if ( nullptr != optionalMutex ) {
std::lock_guard<std::mutex> lockScope( *optionalMutex );
} <- Here the lock ends
foo... <- foo is not protected when optionalMutex was provided
}
我尝试过这样的事情:
bar( std::mutex * optionalMutex = nullptr )
{
...
nullptr == optionalMutex ? 0 : std::lock_guard<std::mutex> lockScope( *optionalMutex );
// this scope should be protected by lock_guard when optionalMutex was provided
foo...
}
或多或少,对我来说唯一可能的解决方案是重复 foo
:
bar( std::mutex * optionalMutex = nullptr )
{
...
if ( nullptr != optionalMutex ) {
std::lock_guard<std::mutex> lockScope( *optionalMutex );
foo...
} else {
foo...
}
}
编译器 gcc 4.9.3
未编译第二个示例并报错:error: expected primary-expression before 'lockScope'
。 更新: Superlokkus 在他的回答中解释了原因。
但我确实想避免任何代码重复,因此也要避免重复 foo
。
我的问题:
有没有一种优雅的方式来解决这个问题,不使用重复的foo
。我知道,我可以使用 lambda 函数来 group foo
但我很好奇是否有其他解决方案。
最佳答案
这个怎么样?
void bar(std::mutex * optionalMutex = nullptr)
{
auto lockScope = (optionalMutex == nullptr) ?
std::unique_lock<std::mutex>()
: std::unique_lock<std::mutex>(*optionalMutex);
}
解释:您的编译器对您之前的语句有问题,因为您不能突然更改三元 ?
的类型表达;即文字 0
不是 std::lock_guard
反之亦然。于是我把两个分支改成了同类型,这里是std::unique_lock<std::mutex>
因为lock_guard
没有设计为在没有有效互斥锁的情况下使用。但还是更喜欢std::lock_guard
超过 std::unique_lock
在更简单的情况下,因为它会使您的代码更具可读性。
您的语句对于编译器也不可行,即即使语法正确,因为变量 lockScope 只会存在于一个分支中。
关于c++ - 有条件地使用 std::lock_guard,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38610307/