C ++不可复制lambda表现可复制吗?

时间:2019-04-12 16:48:07

标签: c++ lambda typetraits

为什么下面的代码编译?

#include <memory>
#include <vector>

int main()
{
    std::vector<std::unique_ptr<int>> uncopyableStuff;
    for(int i = 0; i < 5; ++i)
        uncopyableStuff.emplace_back(std::make_unique<int>(i));
    auto lambda = [uncopyableStuff = std::move(uncopyableStuff)](){};
    static_assert(std::is_copy_constructible<decltype(lambda)>::value);
}

在我看来lambda是不可复制的,因为当我尝试复制它时:

auto copy = lambda;

这给了我一个编译错误(正如我期望的那样)。 lambda和副本可构造性特征是否有例外?

查看链接以获取示例: https://godbolt.org/z/GByclH

编辑:

找出尝试复制时lambda是否将编译的正确方法是什么?我对我对给定可调用对象的理论副本可构造性不感兴趣,但对成功复制构造的发现不感兴趣。向量复制构造函数是用这种方式定义的,这对我来说仍然很奇怪。

1 个答案:

答案 0 :(得分:6)

  

lambda和副本可构造性特征是否有例外?

不。如果您测试std::is_copy_constructible<std::vector<std::unique_ptr<int>>>::value,就会发现它也是正确的。

原因是std::vector具有可访问且不可删除的副本构造函数,即使元素类型不可复制。如果实例化了副本构造函数,则它将无法编译,但这在直接上下文之外,因此std::is_copy_constructible特征无法检测到。

在元素类型的副本可构造性上使std::vector SFINAE的副本构造函数很诱人,但我相信它将破坏将类型本身的向量存储为成员的类型:{{ 1}},因为在这种情况下,struct Node { std::vector<Node> children; }Node的副本可构造性将相互依赖。