auto return 类型不推导引用

auto return type not deducing reference

我有以下代码:

#include <iostream>

struct C {
    int a;
    int& get() { return a; }
};
struct D {
    int a;
    int get() { return a; }
};
template <typename T>
auto foo(T o) { // no sample code is complete without a foo
    return o.get();
}

int main()
{
    C c;
    D d;
    c.a = 2;
    d.a = 42; // no sample code is complete without a 42
    std::cout << "c=" << c.a << ", d=" << d.a << "\n";
    c.get() = 3;
    //d.get() = 43;
    std::cout << "c=" << c.a << ", d=" << d.a << "\n";
    foo(c) = 4;  // <--- why won't this work?
    //foo(d) = 44;
    std::cout << "c=" << c.a << ", d=" << d.a << "\n";
}

为什么标记为编译的行不编译?似乎编译器将 foo<C> 的 return 类型推断为 int 而不是我期望的 int& 。为什么会这样,我怎样才能得到它来推断引用呢?

http://coliru.stacked-crooked.com/a/6ab909680836fd24

给定 auto,它被声明为 non-reference,所以我们正在处理 pass-by-value 的情况。并且 auto follows the rules of template argument deductionint& 的引用部分将被忽略,则推导类型为 int.

您可以改用 decltype(auto) (C++14 起)。

type is decltype(e), where e is the initializer.

template <typename T>
decltype(auto) foo(T&& o) { // no sample code is complete without a foo
    return o.get();
}

return类型推导为decltype(o.get()),根据decltype

的规则

if the value category of expression is lvalue, then decltype yields T&;

c.get() returns int&,这是一个左值,然后我们得到 return 类型 int& 而不是 int

顺便说一句:请注意,如果 o 仍然通过 by-value,returned 引用将被悬挂。