[BUG] Cannot chain a member function call after constructing an object
bluetarpmedia opened this issue · comments
Describe the bug
Cannot chain a member function call on the same source code line after constructing an object.
To Reproduce
I'm trying to translate this C++ code:
using namespace std::chrono_literals;
std::thread([]{ std::this_thread::sleep_for(1000ms); }).detach();
into Cpp2:
using namespace std::chrono_literals;
_: std::thread = (:() = std::this_thread::sleep_for(1000ms);).detach();
But the detach
call is invoked on the lambda instead of on the std::thread
object.
std::thread auto_1 {CPP2_UFCS(detach)(([]() mutable -> void { std::this_thread::sleep_for(1000ms); }))};
which leads to a C++ compiler error:
main.cpp2:6:25: error: no matching function for call to object of type '(lambda at main.cpp2:6:25)'
6 | std::thread auto_1 {CPP2_UFCS(detach)(([]() mutable -> void { std::this_thread::sleep_for(1000ms); }))};
| ^~~~~~~~~~~~~~~~~
Repro on Godbolt
This syntax does work:
std::thread(:() = std::this_thread::sleep_for(1000ms);).detach();
but I want to be explicit and use the _
wildcard.
Alternative syntaxes attempted
- This alternative syntax:
_:= std::thread(:() = std::this_thread::sleep_for(1000ms);).detach();
doesn't work because of the "anonymous name + type" rule:
error: an object can have an anonymous name or an anonymous type, but not both at the same type (rationale: if '_ := f();' were allowed to keep the returned object alive, that syntax would be dangerously close to '_ = f();' to discard the returned object, and such importantly opposite meanings deserve more than a one-character typo distance; and explicit discarding gets the nice syntax because it's likely more common)
- This syntax comes close but doesn't work either:
_: std::thread = std::thread(:() = std::this_thread::sleep_for(1000ms);).detach();
because it lowers to:
std::thread auto_1 {CPP2_UFCS(detach)(std::thread([]() mutable -> void { std::this_thread::sleep_for(1000ms); }))};
which is effectively doing this:
std::thread auto_1 {
std::thread([]() { }).detach()
};
Ah, I just realised my mistake, the syntax I was trying to write would be invalid, since I can't assign the result of detach
to an anonymous object, and its type wouldn't be std::thread
.