使用不可复制类的模板类型扣除

使用不可复制类的模板类型扣除

本文介绍了使用不可复制类的模板类型扣除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个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.

这篇关于使用不可复制类的模板类型扣除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 06:41