问题描述
假设我有一个autolocker类,看起来像这样:
Suppose I have an autolocker class which looks something like this:
template <T>
class autolocker {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
~autolocker() {
lock->unlock();
}
private:
autolocker(const autolocker&);
autolocker& operator=(const autolocker&);
private:
T *lock;
};
显然目标是能够使用带有lock / unlock方法的autolocker
Obviously the goal is to be able to use this autolocker with anything that has a lock/unlock method without resorting to virtual functions.
目前,使用这种方法很简单:
Currently, it's simple enough to use like this:
autolocker<some_lock_t> lock(&my_lock); // my_lock is of type "some_lock_t"
但是这是非法的:
autolocker lock(&my_lock); // this would be ideal
是否还有模板类型演绎在我的autolocker是不可复制)。
Is there anyway to get template type deduction to play nice with this (keep in my autolocker is non-copyable). Or is it just easiest to just specify the type?
推荐答案
是的,您可以使用范围保护技术
Yes you can use the scope-guard technique
struct autolocker_base {
autolocker_base() { }
protected:
// ensure users can't copy-as it
autolocker_base(autolocker_base const&)
{ }
autolocker_base &operator=(autolocker_base const&)
{ return *this; }
};
template <T>
class autolocker : public autolocker_base {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
autolocker(const autolocker& o)
:autolocker_base(o), lock(o.lock)
{ o.lock = 0; }
~autolocker() {
if(lock)
lock->unlock();
}
private:
autolocker& operator=(const autolocker&);
private:
mutable T *lock;
};
然后写一个创建autolocker的函数
Then write a function creating the autolocker
template<typename T>
autolocker<T> makelocker(T *l) {
return autolocker<T>(l);
}
typedef autolocker_base const& autolocker_t;
您可以这样写:
autolocker_t lock = makelocker(&my_lock);
一旦const引用超出作用域,将调用析构函数。它不需要是虚拟的。至少GCC 。
Once the const reference goes out of scope, the destructor is called. It doesn't need to be virtual. At least GCC optimizes this quite well.
很遗憾,这意味着你必须让你的储物柜可复制,因为你需要从maker函数返回它。但旧对象不会尝试解锁两次,因为它的指针设置为0时,它的复制,所以它的安全。
Sadly, this means you have to make your locker-object copyable since you need to return it from the maker function. But the old object won't try to unlock twice, because its pointer is set to 0 when it's copied, so it's safe.
这篇关于使用不可复制类的模板类型扣除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!