防止创建临时对象

时间:2014-04-17 10:09:17

标签: c++11 c++14

我有五年前在这里提出的同样问题: Disallowing creation of the temporary objects

我再次提出这个问题的原因是我对C ++ 11和C ++ 14技术特别感兴趣,以防止构建临时工。

一个想法是使用"右值参考* this":

class ScopedLock
{
public:
  void enable() && = delete;

  void enable() &
  {
    is_enabled = true;
  }

  ~ScopedLock()
  {
    if (!is_enabled) {
      std::cerr << "ScopedLock misuse." << std::endl;
      std::terminate();
    }
  }

private:
  bool is_enabled = false;
};



int main()
{

  // OK
  ScopedLock lock;
  lock.enable();

  // Compilation error.
  ScopedLock().enable();

  // std::terminate
  ScopedLock();

  // std::terminate
  ScopedLock lock;

  std::cout << "Y" << std::endl;
}

也许有更好的方法?

1 个答案:

答案 0 :(得分:1)

以下是same question的两个重要答案的C ++ 11版本。我不应该为此付出太多的荣誉,所以考虑投票选择原来的答案

user1773602&#39; s answer

这个想法是定义一个删除的函数,其名称与类相同:

class ScopedLock {
    // ...  
};

void ScopedLock(...) = delete;

用法不寻常,这可能(非常?)不方便:

  class ScopedLock a; // OK             :-| but requires keyword 'class'
  ScopedLock b;       // Compiler error :-(
  ScopedLock();       // Compiler error :-)

Johannes Schaub - litb&#39; answer

如果您不介意发生运行时错误(如OP似乎那样)而不是编译时错误,那么您可以试试这个。

基本思想是ScopedLock构造函数的临时绑定将在ScopedLock对象之前或之后被销毁,具体取决于后者是否是临时的。

class ScopedLock {

  bool flag_ = true;

  struct Flag {
    bool* flag;
    ~Flag() {
      *flag = false;
    }
  };

public:

  ScopedLock(Flag&& f = Flag()) {
    f.flag = &flag_;
  }

  ~ScopedLock() {
    if (flag_) {
      std::cerr << "ScopedLock misuse\n.";
      std::terminate();
    }
  }

};

有了这个,我们有

ScopedLock a; // OK
ScopedLock(); // Runtime error