The output from the below program will all be 1A which is A when going through c++filt -t. I can see that the return type is deduced as value type rather than rvalue reference type when returning with std::move. It makes sense for most use cases of returning with std::move, but what is the reason for this? std::move returns an rvalue reference, but why is the return type automatically deduced as a value type?
#include <iostream>
#include <memory>
#include <utility>
#include <typeinfo>
struct A
: std::unique_ptr<int>
{
auto f()
{
return A();
}
auto g()
{
return std::move(A());
}
};
int main()
{
std::cout << typeid(decltype(A().f())).name() << ' ';
std::cout << typeid(decltype(A().g())).name() << ' ';
std::cout << typeid(A).name() << '\n';
}
You have two separate issues:
typeid strips referenceness then top-level cv-qualification; typeid(int), typeid(const int) and typeid(const int&&) are the same thing. To test for actual type, use std::is_same; Boost.TypeIndex has type_id_with_cvr. There's also the trick where you do template<class T> class TD;, attempt to define a variable of type TD</*type to be checked*/>, and read out the type from error message generated by the compiler.but this is harmless here; both f() and g() indeed return A by value:
auto f() { return /* stuff */; } uses the auto rules, which never deduces a reference type. This is actually usually what you want - you don't really want to accidentally return references to things that have already died - which indeed is what your g() would do if it returned a reference!To get "perfect returning", use decltype(auto).
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