自动返回类型不推导参考

时间:2019-06-03 15:01:45

标签: c++ c++11 auto 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";
}

为什么标记为行的行不能编译?看来编译器在推导foo<C>的返回类型为int而不是我期望的int&。为什么会这样呢?我又该如何推断出参考呢?

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

1 个答案:

答案 0 :(得分:6)

给出auto,它被声明为非引用,因此我们要处理按值传递的情况。 auto遵循template argument deduction的规则; 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();
}

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

  

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

c.get()返回int&,它是一个左值,然后我们得到int&的返回类型int的代言人。

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