【问题标题】:VC++ 15 calls the wrong copy constructor for lambda capture?VC++ 15 为 lambda 捕获调用了错误的复制构造函数?
【发布时间】:2017-04-18 10:14:03
【问题描述】:

考虑以下程序:

#include <iostream>
struct X {
  X () = default;
  X (X &) { std::cout << "non-const called" << std::endl; }
  X (X const &) { std::cout << "const called" << std::endl; }
  int i () const { return 7; }
};

auto f () {
  X x;
  auto lambda = [=]() { return x.i(); };
  return lambda;
}

int main()
{
  auto lambda = f();
  std::cout << lambda () << std::endl;
  return 0;
}

使用 VC++15,我得到了输出

const called
const called
7

使用 Clang 3.9,我得到了

non-const called
7

这里哪个编译器是正确的?

【问题讨论】:

  • This 可能会引起您的兴趣。坦率地说,我不认为你的问题是重复的:)
  • 值得注意的是,启用优化后,VC 还应用 RVO,导致只调用一次 X(X const&amp;)
  • @skypjack:你确定 lambdas 构造了一个 const 成员吗? ideone.com/RQ7OjC我觉得数据成员不一定是const,只有operator ()是。
  • @JohnB 够公平的。我也在更正答案。很好的收获。
  • @Oktalist 还是应该打给X(X &amp;),对吧?

标签: c++ visual-c++ lambda clang copy-constructor


【解决方案1】:

我会说 clang 是对的。
当 lambda 捕获 x 并且返回值的构造函数被优化时,最适合的构造函数只被调用一次。
这就是为什么你只获得一个 non-const called


有关复制省略和 RVO 的更多详细信息,请参阅 herehere

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多