c++c++17autotype-deductionreturn-type-deduction

Deduced type with 'auto &&' as function return type


In the following snippet, the function B::f() is a "wrapper" around the function A::f(). But I assume that A::f() return type is an "opaque" type which I don't know if it has a value or reference semantics. So I cannot use auto or const auto & as return type for B::f(). I thought that auto && would do the trick, but it does not as auto && is deduced as A::OpaqueType &... Is it possible here to avoid writing A::OpaqueType?

#include <iostream>

struct A {
    using OpaqueType=int; // But it could have been `const int &`

    OpaqueType f() const {
        return i;
    }

    int i=42;
};

struct B {
    // how could I use `auto` here to avoid writing the `A::OpaqueType`?
    // I would have expected that `auto &&` would do the trick but it does not
    A::OpaqueType f() const { 
        return a.f();
    }

    A a;
};

int main()
{
    B b;
    std::cout << b.f() << std::endl; 
}

The following snippet confuses me, as I would have expected that the return type of f() and g() would be int, but it is int & for f() and int && for g() (I don't even understand why it is not the same)... How this can be explained?

#include <iostream>
 
auto &&f() {
    int i=42;
    return i;
}

struct A {
    int f() {return i;}

    int i=42;
};

auto &&g() {
    A a;
    return a.f();
}

int main()
{
   if (std::is_same_v<decltype(f()), int &>) {
       std::cout << "f() return type is 'int &'\n";
   }
   if (std::is_same_v<decltype(g()), int &&>) {
       std::cout << "g() return type is 'int &&'\n";
   }
}

Thanks!


Solution

  • Pretty sure what you are looking for is decltype(auto). This will return by value if the expression in the return statement returns by value, and it will return by reference if the expression in the return statement returns by reference. That would give you

    decltype(auto) f() const { 
        return a.f();
    }