Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

auto return type deduction with `std::move`

Tags:

c++

c++14

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';
}

1 Answers

You have two separate issues:

  1. The tool you are using to check the return type is not fit for purpose.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:

  1. 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).

like image 78
T.C. Avatar answered Mar 03 '26 16:03

T.C.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!