在C ++中,可以在int (x) = 0;
之类的括号内声明变量。但似乎如果您使用this
而不是变量名,则使用构造函数:A (this);
调用A::A(B*)
。所以第一个问题是为什么它与this
不同,是因为变量不能命名为this
?更复杂的是,让this
放入lambda -
struct B;
struct A
{
A (B *) {}
};
struct B
{
B ()
{
[this] { A (this); } ();
}
};
现在gcc调用A::A(B*)
,msvc打印有关缺少默认构造函数和clang打印expected expression
(https://godbolt.org/g/Vxe0fF)的错误。它甚至在msvc中更有趣 - 它确实创建了可以使用的名称为this
的变量,所以它肯定是一个bug(https://godbolt.org/g/iQaaPH)。哪种编译器是正确的,这种行为的原因是什么?
答案 0 :(得分:1)
在C ++标准§5.1.5(C ++ 11第7条,第8条后标准)中[expr.prim.lambda]:
lambda-expression的复合语句产生函数调用操作符的函数体(8.4),但是 为了查找名称(3.4),确定它的类型和值(9.2.2.1)并转换id- 使用(* this)(9.2.2)将非静态类成员引用到类成员访问表达式中的表达式, 复合语句在lambda表达式的上下文中考虑。 [例如:
struct S1 {
int x, y;
int operator()(int);
void f() {
[=]()->int {
return operator()(this->x + y); // equivalent to S1::operator()(this->x + (*this).y)
// this has type S1*
};
}
};
- 结束示例]
因此,gcc是对的。您会注意到他们捕获this
这一事实也不例外。然而,在你捕获*this
的情况下,它们是自C ++ 14以来的精度,仍然在§5.1.5(第17条)中:
如果*这是由副本捕获的,则每次使用它都会转换为指向相应的指针 闭包类型的未命名数据成员,强制转换(5.4)到此类型。