gpt4 book ai didi

c++ - MSVC 对 C++20 中闭包类型的默认构造函数的行为有所不同

转载 作者:行者123 更新时间:2023-12-04 11:50:00 25 4
gpt4 key购买 nike

standard

The closure type associated with a lambda-expression has no default constructor if the lambda-expression has a lambda-capture anda defaulted default constructor otherwise. It has a deleted copy assignment operator ifthe lambda-expression has a lambda-capture and defaulted copy and move assignmentoperators otherwise. It has a defaulted copy constructor and a defaulted move constructor(15.8). [ Note: These special member functions are implicitly defined as usual, and mighttherefore be defined as deleted. — end note ]


Cppreference具体说(强调我的)

If no captures are specified, the closure type has a defaulted default constructor. Otherwise, it has no default constructor (this includes the case when there is a capture-default, even if it does not actually capture anything).


If no captures are specified, the closure type has a defaulted copy assignment operator and a defaulted move assignment operator. Otherwise, it has a deleted copy assignment operator (this includes the case when there is a capture-default, even if it does not actually capture anything).


所以以下必须是有效的。
auto lambda = [&](){};

static_assert(!std::is_default_constructible<decltype(lambda)>::value);
static_assert(!std::is_assignable<decltype(lambda), decltype(lambda)>::value);
但是 MSVC 说他们是 default_constructible , 等等。
https://godbolt.org/z/E6EW3rMcE
由于论文没有具体提到默认捕获,但实际上没有提到捕获,我想知道这是MSVC缺陷还是允许实现定义。

更新
我已向 Microsoft 报告了此错误,并将在即将发布的版本中修复 link .

最佳答案

这里的标准很明确。在 [expr.prim.lambda.closure]/13 :

The closure type associated with a lambda-expression has no default constructor if the lambda-expression has a lambda-capture and a defaulted default constructor otherwise.


此规则基于 lambda 的词法构成,而不是我们为确定是否捕获到任何内容而进行的语义分析。这是语法上的区别。
如果 lambda 以 [] 开头,则它没有 lambda 捕获,因此具有默认的默认构造函数。
如果 lambda 以 [&] 开头,那么它有一个 lambda 捕获,因此没有默认构造函数 - 无论是否捕获任何东西。是否捕获任何东西都没有关系。
cppreference 在此处添加的说明是正确且有帮助的。 lambda [&](){}不是默认可构造的(或者,按照相同的逻辑,不可分配)。 所以,是的,这是一个 MSVC 错误。

请注意,这与我们必须确定是否可以将 lambda 转换为函数指针的规则相同:是否存在 lambda 捕获,而不是是否有任何捕获。因此, [](){}可转换为 void(*)()但是 [&](){}不是。

关于c++ - MSVC 对 C++20 中闭包类型的默认构造函数的行为有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68363717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com