Can anyone explain to me why I have to explicitly write "this->" in the second lambda even tho I captured everything ?
The error message for completeness:
cannot call member function 'result_t test::get()' without object
#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
using result_t = std::function<void()>;
struct test
{
bool noMore = false;
result_t get()
{
return [this]
{
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
if(not noMore)
{
noMore = true;
std::for_each(vec.begin(), vec.end(),
[&](const auto& i)
{
auto value1 = this->get(); // compiles
auto value2 = get(); // error
});
}
};
}
};
int main() {
test t;
t.get()();
}
Godbolt
This is a gcc bug. From [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.3.2) and transforming id-expressions referring to non-static class members into class member access expressions using
(*this)
(9.3.1), 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 ]
In this case, get()
should be equivalent to test::get()
, and this
is captured, so this is well-formed. clang compiles the code as-is. gcc compiles the code if you change i
to be passed as an int
instead of as const auto&
, which is irrelevant to how get()
is looked up.
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