C ++不可复制的lambda是否可以复制?

问题描述 投票:10回答:1

为什么以下代码编译?

#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和复制可构造性特征是否有一些例外?

请参阅godbolt示例链接:https://godbolt.org/z/GByclH

编辑:

找出lambda在尝试复制时是否会编译的正确方法是什么。我geuss我对给定可调用的理论副本可构造性不感兴趣,但检测到成功的复制构造。我似乎很奇怪,矢量复制构造函数是以这种方式定义的。

c++ lambda typetraits
1个回答
6
投票

lambda和复制可构造性特征是否有一些例外?

不。如果你测试std::is_copy_constructible<std::vector<std::unique_ptr<int>>>::value,你会发现它也是如此。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.