为什么以下代码编译?
#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我对给定可调用的理论副本可构造性不感兴趣,但检测到成功的复制构造。我似乎很奇怪,矢量复制构造函数是以这种方式定义的。
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; }
,因为在这种情况下,副本Node
和std::vector<Node>
的可构造性将是相互依赖的。