In C++ it's possible to declare variable inside parentheses like int (x) = 0;
. But it seems that if you use this
instead of variable name, then constructor is used instead: A (this);
calls A::A(B*)
. So the first question is why it's different for this
, is it because variables can't be named this
? And to complicate matters a bit lets put this
inside a lambda -
struct B;
struct A
{
A (B *) {}
};
struct B
{
B ()
{
[this] { A (this); } ();
}
};
Now gcc calls A::A(B*)
, msvc prints error about missing default constructor and clang prints expected expression
(https://godbolt.org/g/Vxe0fF). It's even funnier in msvc - it really creates variable with name this
that you can use, so it's definitely a bug (https://godbolt.org/g/iQaaPH). Which compiler is right and what are the reasons for such behavior?
In the C++ standard §5.1.5 (article 7 for C++11, article 8 later standard) [expr.prim.lambda]:
The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), determining the type and value of this (9.2.2.1) and transforming id- expressions referring to non-static class members into class member access expressions using (*this) (9.2.2), the compound-statement is considered in the context of the lambda-expression. [ Example:
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*
};
}
};
— end example ]
Thus, gcc is right. You will notice that their is no exception about the fact that you are capturing this
. Their is, however a precision since C++14 in the case where you capture *this
, still in §5.1.5 (article 17):
If *this is captured by copy, each odr-use of this is transformed into a pointer to the corresponding unnamed data member of the closure type, cast (5.4) to the type of this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With