I know that std::move
casts an object to rvalue reference:
Return value
static_cast<typename std::remove_reference::type&&>(t)
For a temporary object with prolonged lifetime, I thought it does not make much sence to do std::move
on it since it is already dummy &&
.
Here is an example:
#include <utility>
int main()
{
struct dummy {};
const auto &c = [](dummy &&){};
dummy &&d = dummy{};
c(dummy{});
c(std::move(d));
// c(d); // does not compile
[](auto &&){}(d); // compiles
}
https://godbolt.org/z/nqM75KK7M
- Passing a temporary from
dummy{}
compiles. - Passing a temporary
auto &&d
to a generic lambda (that acceptsauto &&
) works, and I expect it to be resolved todummy&&
at compile-time. - Passing a temporary
auto &&d
compiles only withstd::move(d)
. Why? (even clang-tidy says that usingstd::move
on trivially copiable type has no effect.)
<source>: In function 'int main()':
<source>:14:4: error: no match for call to '(const main()::<lambda(main()::dummy&&)>) (main()::dummy&)'
14 | c(d); // does not compile
| ~^~~
<source>:14:4: note: candidate: 'void (*)(main()::dummy&&)' (conversion)
<source>:14:4: note: conversion of argument 2 would be ill-formed:
<source>:14:5: error: cannot bind rvalue reference of type 'main()::dummy&&' to lvalue of type 'main()::dummy'
14 | c(d); // does not compile
| ^
<source>:9:19: note: candidate: 'main()::<lambda(main()::dummy&&)>' (near match)
9 | const auto &c = [](dummy &&){};
| ^
<source>:9:19: note: conversion of argument 1 would be ill-formed:
<source>:14:5: error: cannot bind rvalue reference of type 'main()::dummy&&' to lvalue of type 'main()::dummy'
14 | c(d); // does not compile
| ^
Compiler returned: 1