This is redundant and confusing. Just because I can write std::add_pointer_t<void> instead of void* or std::add_lvalue_reference_t<Foo> (or Foo bitand ) instead of Foo& does not mean that I should.
It also matters in other contexts:
auto&& a = f();
and therefore, if Foo is something that can be repeated,
for(const auto& p : f()) {}
And in your example, if the assignment operator is implemented as copy-and-swap ( operator=(Foo) ), then foo = std::move(f()) forcibly executes a non-elite move, while foo = f() can overcome the transition of f() return the value for the operator= argument.
source share