【发布时间】:2014-06-30 01:20:38
【问题描述】:
我一直在寻找另一个问题 (this one) 的解决方案。似乎应该可以为可以解锁互斥锁的unique_ptr 实例创建自定义删除器。
例如,
#include <mutex>
#include <memory>
struct LockDeleter
{
std::unique_lock<std::mutex> lock_;
LockDeleter(std::mutex& m) : lock_(m) {}
void operator()(void*) { lock_.unlock(); }
};
int main()
{
std::mutex moo;
{
std::unique_ptr<int, LockDeleter> ptr(new int(42), LockDeleter(moo));
}
}
在VS2013 express下编译,我得到
错误 1 错误 C2280: 'std::unique_lock::unique_lock(const std::unique_lock &)' : 试图引用已删除的函数
和
此诊断发生在编译器生成的函数“LockDeleter::LockDeleter(const LockDeleter &)”中
现在,我似乎无法强制移动锁定删除器实例,而不是使用std::move 复制...即使向LockDeleter 添加显式移动构造函数也不会帮助,被删除的复制构造函数仍然被调用。
那么,我是在做一些傻事,还是必须 unique_ptr 删除器始终是可复制构造的?
【问题讨论】:
-
似乎是编译器错误; gcc 和 clang 都可以。
-
@ecatmur:很有趣。在我的实验过程中,我注意到 vs2013 也不支持
std::bind移动参数值(参见示例 here)所以我猜 VS2013 在不可复制对象方面存在多个微妙问题。 -
@ecatmur:确实,启动我的一些笨拙的旧 debian VM 表明 GCC 4.6 和 4.8 似乎都很乐意编译这段代码。随意发布这个小评论作为答案。
-
VS2013 RTM 不会生成隐式移动成员(CTP 版本会生成)。您需要自己实现移动构造函数。编辑:does not seem to help. 一定是标准库错误?
-
挖掘 VS12 的
<memory>:unique_ptr的构造函数将删除器参数按值传递给基类,因此(错误地)实例化删除器的复制构造函数。
标签: c++ c++11 move unique-ptr