什么是'auto&& i = foo();`的意思

时间:2014-03-27 12:51:47

标签: c++11

请解释自动类型推导与移动语义一起使用时的工作原理:

#include <iostream>

template <typename T>
struct A {
    static void type() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

float& bar() {
    static float t = 5.5;
    return t;
}

int foo() {
    return 5;
}

int main() {
    auto &&a1 = foo();  // I expected auto -> int    (wrong)
    auto &&a2 = bar();  // I expected auto -> float& (correct)

    A<decltype(a1)>::type();
    A<decltype(a2)>::type();
}

输出结果为:

static void A<T>::type() [with T = int&&]
static void A<T>::type() [with T = float&]

2 个答案:

答案 0 :(得分:3)

auto&&(就像函数模板参数中T&&一样T是该函数模板的模板参数)遵循与其他扣减略有不同的规则 - 它是&#39}非正式地称为&#34;通用参考。&#34;

我们的想法是,如果初始化者是X类型的左值,则auto会推断为X&。如果它是X类型的右值,则auto会推断为X。在这两种情况下,都会正常应用&&。根据参考折叠规则,X& &&变为X&,而X &&仍为X&&

这意味着,在a1案例中,auto确实已推断为int,但a1自然会被声明为int&&类型,而且decltype(a1) #39; s auto给你的东西。

与此同时,a2中的float&a2decltype(a2)的类型也是auto -> inta1再次确认。< / p>

换句话说,您希望第一种情况中的auto &&a1是正确的,但auto a1的类型是{{1}},而不只是{{1}}。

答案 1 :(得分:2)

auto &&a1 = foo();

foo()的返回类型是int。由于您将a1声明为auto&&,因此它会扩展为int&&,这就是您获得的a1类型。

auto &&a2 = bar();

bar()的返回类型是浮动&amp ;.由于您将a2声明为auto&&,因此它会扩展为float& &&并按照规则转换为float&

This answer解释了通用参考扩展的规则:

&& -> &&
&& & -> &
& && -> &
&& && -> &&