为什么下面的代码编译?
#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是否将编译的正确方法是什么?我对我对给定可调用对象的理论副本可构造性不感兴趣,但对成功复制构造的发现不感兴趣。向量复制构造函数是用这种方式定义的,这对我来说仍然很奇怪。
答案 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
的副本可构造性将相互依赖。