2014-03-19 73 views
18

为什么的std :: lock_guard不可移动的,它将使代码,以便好得多:为什么std :: lock_guard不能移动?

auto locked = lock_guard(mutex); 

,而不是

std::lock_guard<std::mutex> locked(mutex); 

有什么问题与创建您自己的版本,如:

template <typename T> class lock_guard_ 
{ 
    T* Mutex_; 
    lock_guard_(const lock_guard_&) = delete; 
    lock_guard_& operator=(const lock_guard_&) = delete; 
public: 
    lock_guard_(T& mutex) : Mutex_(&mutex) 
    { 
    Mutex_->lock(); 
    } 
    ~lock_guard_() 
    { 
    if(Mutex_!=nullptr) 
     Mutex_->unlock(); 
    } 
    lock_guard_(lock_guard_&& guard) 
    { 
    Mutex_ = guard.Mutex_; 
    guard.Mutex_ = nullptr; 
    } 
}; 

template <typename T> lock_guard_<T> lock_guard(T& mutex) 
{ 
    return lock_guard_<T>(mutex); 
} 

任何根本原因,这将是一个坏主意,使其可移动?

+0

那么,你有'unique_lock'。这可能只是使界面尽可能简单。 – ecatmur

+0

谢谢,我忽略了unique_lock :-)所以我想这回答了我的问题:没有没有理由。 Imo使它可移动并不会使界面更加复杂,但更加可用并且与现代C++兼容。 – valoh

+1

@valoh:如果它是可移动的,它将需要一个不锁定锁的状态。这使得它成为多余的,因为它将提供与'unique_lock'完全相同的功能(尽管我会认为它无论如何都是多余的)。因此,如果'lock_guard'作为一个单独的课程是需要的,它不能真正移动。 – Grizzly

回答

13

lock_guard总是订婚;它总是持有对互斥体的引用,并始终在其析构函数中解锁它。如果它是可移动的,那么它需要持有一个指针而不是引用,并在其析构函数中测试指针。这看起来可能是一个微不足道的成本,但它是C++的哲学,你不支付你不使用的东西。

如果你想要一个可移动(和可释放)锁,你可以使用unique_lock

您可能感兴趣n3602 Template parameter deduction for constructors,它不需要make_功能。它不会在C++ 14中,但我们可以希望C++ 17。

+0

N3602是[EWG问题60](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3836.html#60)。 EWG绝对赞成这篇论文,但也有一些问题需要解决。 – Casey

10

你可以这样做:

auto&& g = std::lock_guard<std::mutex> { mutex }; 

显然,这不是完全满意,因为这不进行扣除。你在推导工厂尝试几乎没有挽救的事实,你需要使用列表初始化返回一个不可移动的物体:

template<typename Mutex> 
std::lock_guard<Mutex> lock_guard(Mutex& mutex) 
{ 
    mutex.lock(); 
    return { mutex, std::adopt_lock }; 
} 

它允许auto&& g = lock_guard(mutex);

(这种尴尬的舞蹈std::adopt_lock是由于一元构造是明确的,所以我们不可以做return { mutex };因为这是不允许的转换,而临时的return std::lock_guard<Mutex> { mutex };执行列表初始化 - 这是我们不能再进入返回值。)

+0

这很漂亮,有点可怕,我可能只是偷了它。 :p –

+2

这很酷,但为什么额外的聚合水平?它似乎没有它的工作:https://ideone.com/KDs8qI –

+0

@VaughnCato这可能是我的一个误解,因为我认为只适用于聚合的语言似乎同样适用于非聚合。诚然,这些并不是我最喜欢的标准领域,所以我欢迎任何关于它们的光芒。感谢您的提醒。 –

相关问题