【问题标题】:Prevent the creation of temporary objects防止创建临时对象
【发布时间】:2014-06-01 13:18:23
【问题描述】:

五年前我也有同样的问题: 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;
}

也许有更好的方法?

【问题讨论】:

  • 如果你写 void enable() &amp;&amp; = delete; 这实际上会阻止像 ScopedLock().enable(); 这样的东西编译。但是,它不会阻止 ScopedLock() 编译。
  • 好点。绝对是一个进步。
  • 如果可以在析构函数中添加一个右值引用限定符,问题就解决了。但据我所知,这是不可能的。
  • template&lt;typename T&gt;typename std::decay&lt;T&gt;::type&amp; as_lvalue(T&amp;&amp;t){return t;} 然后 as_lvalue( ScopedLock{} ).enable(); -- 所以上面的方法不起作用。
  • 作为一个 XY 问题,您可以将锁与锁定的数据结合起来。仅通过锁类的实例提供对数据的访问。

标签: c++11 c++14


【解决方案1】:

这里是same question 的两个出色答案的 C++11 版本。我对此不值得称赞,因此请考虑为原始答案投票。

user1773602 的answer

这个想法是定义一个与类同名的已删除函数:

class ScopedLock {
    // ...  
};

void ScopedLock(...) = delete;

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

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

Johannes Schaub - litb的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多