有一个构造函数,但有两个析构函数。

3

我花了一些时间来找到错误,但仍不知道如何解决它。

从代码上看,只有一个构造函数调用,但它却调用了两次析构函数。

代码:

struct A
{
  A()
  {
      std::cout << "C'tor" << std::endl;
  }

  A(A&&)
  {
      std::cout << "M'tor" << std::endl;
  }

  A(const A&) = delete;
  A& operator=(const A&) = delete;
  A& operator=(A&&) = delete;

  ~A()
  {
      std::cout << "D'tor" << std::endl;
  }
};

int main()
{
    auto lambda = [](int i){
        A a;
        if (i == 0)
            return std::move(a);
    };

    lambda(1);
    return 0;
}

输出:

C'tor                                                                                                                                                                        
D'tor                                                                                                                                                                        
D'tor

这怎么会发生呢?编译器至少应该为我生成一个警告吧?你觉得呢?

2个回答

10
lambda的返回类型被推断为A,但只要i != 0,就不会返回任何内容,就像你的示例一样。从非void函数中返回空值是未定义行为,也就是说,任何事情都可能发生。

2

@pasbi说得对,C++2a(GNU)编译器明确警告了这一点:

prog.cc: In lambda function:
prog.cc:30:29: warning: moving a local object in a return statement prevents copy elision [-Wpessimizing-move]
30 |             return std::move(a);
  |                    ~~~~~~~~~^~~
prog.cc:30:29: note: remove 'std::move' call
prog.cc:31:5: warning: control reaches end of non-void function [-Wreturn-type]
31 |     };
  |     ^

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接