自动返回类型不推导参考

Bar*_*uch 7 c++ auto c++11 return-type-deduction

我有以下代码:

#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";
}
Run Code Online (Sandbox Code Playgroud)

为什么行未标记为可编译?看来,copiler推断的返回类型foo<C>为be,int而不是int&我期望的。为什么会这样,我又如何得到它来推断参考呢?

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

son*_*yao 6

给定auto,它被声明为非引用,因此我们要处理按值传递情况。并auto遵循模板参数推导规则; 的引用部分int&将被忽略,则推导类型为int

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

类型是decltype(e),其中e是初始值设定项。

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

返回类型推导为decltype(o.get()),根据的规则decltype

如果表达式的值类别为lvalue,则decltype产生T&;

c.get()回报int&,这是一个左值,那么我们得到的返回类型int&的insteand int

顺便说一句:请注意,如果o仍然按值传递,则返回的引用将被悬挂。