带初始化器的Lambda函数和不带初始化器的Lambda函数在功能上是否相同?

4
假设复制构造函数和复制赋值运算符没有副作用,以下两个代码段是否完全相同,不考虑response的类型和限定符?
auto foo = [response]() {
    do_something(response);
};

And

auto foo = [response = response]() {
    do_something(response);
};

看起来它们做的事情完全相同——复制对象响应,但在某些情况下,仅第二个版本编译。

以下是一个示例程序,以演示此问题:

#include <memory>
using namespace std;
void do_something() {
}
int main() {
    auto au = [](auto callback) {
        callback();
    };
    auto x = [&au](shared_ptr<int> response) {
        au([response = move(response)]() mutable {
            auto foo = [response/* = response*/]() { // uncomment and it will work
                do_something();
            };
        });
    };
    x(make_shared<int>(100));
}

看起来这个问题需要使用std::shared_ptr作为response,但我不确定原因。我知道复制一个shared_ptr并不会复制实际的资源(如int),但我无法理解它如何导致代码无法编译。我一直认为前两个代码片段完全相同。
如果需要的话,我使用MSVC 2015并以Debug x86编译,但我认为将其编译为Release或x64会得到相同的结果。

这个被注释的版本在gcc和clang上都能正常工作。这可能是一个编译器的错误。 - eerorika
1
有时候捕获变量所使用的语法很重要,但似乎没有一种适用于你的代码。 - Piotr Skotnicki
这两种形式的名称查找方式有所不同,不确定这是否导致了MSVC的问题。 - TartanLlama
1个回答

3
似乎是编译器的问题。最新的VisualC++ v19.10.24903.0 可以编译它。你可以在这里在线尝试:这里

1
看起来是这样。我刚在这里进行了在线测试(http://rextester.com/l/cpp_online_compiler_visual),问题在那里也存在。 - Bernard
@Bernard 确切如此 :) - AMA

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