C++11 "auto"语义

C++11 "auto" semantics

本文关键字:语义 auto C++11      更新时间:2023-10-16

当我使用c++ 11 auto时,关于它将解析为值还是引用的类型推导规则是什么?

E。G,有时候很明显:

auto i = v.begin(); // Copy, begin() returns an iterator by value

这些不太清楚:

const std::shared_ptr<Foo>& get_foo();
auto p = get_foo(); // Copy or reference?
static std::shared_ptr<Foo> s_foo;
auto sp = s_foo; // Copy or reference?
std::vector<std::shared_ptr<Foo>> c;
for (auto foo: c) { // Copy for every loop iteration?

规则很简单:它是如何声明的。

int i = 5;
auto a1 = i;    // value
auto & a2 = i;  // reference

下一个例子证明了它:

#include <typeinfo>
#include <iostream>    
template< typename T >
struct A
{
    static void foo(){ std::cout<< "value" << std::endl; }
};
template< typename T >
struct A< T&>
{
    static void foo(){ std::cout<< "reference" << std::endl; }
};
float& bar()
{
    static float t=5.5;
    return t;
}
int main()
{
    int i = 5;
    int &r = i;
    auto a1 = i;
    auto a2 = r;
    auto a3 = bar();
    A<decltype(i)>::foo();       // value
    A<decltype(r)>::foo();       // reference
    A<decltype(a1)>::foo();      // value
    A<decltype(a2)>::foo();      // value
    A<decltype(bar())>::foo();   // reference
    A<decltype(a3)>::foo();      // value
}
输出:

value
reference
value
value
reference
value

§7.1.6.4 [dcl.spec.auto] p6

一旦根据8.3确定了声明符id的类型,使用声明符id声明的变量的类型将使用模板参数推导规则从其初始化器的类型确定。

这意味着auto在函数调用期间建模模板参数推导。

template<class T>
void f(T){} // #1, will also be by-value
template<class T>
void g(T&){} // #2, will always be by-reference

注意#1将始终复制传递的实参,无论传递的是引用还是其他参数。(除非您特别指定模板参数,如f<int&>(intref);)

无论你从右边(of "=")得到什么都不是引用。更具体地说,表达式的结果永远不是引用。在这种情况下,请注意示例中结果之间的差异。

#include <typeinfo>
#include <iostream>
template< typename T >
struct A
{
    static void foo(){ std::cout<< "value" << std::endl; }
};
template< typename T >
struct A< T&>
{
    static void foo(){ std::cout<< "reference" << std::endl; }
};
float& bar()
{
    static float t=5.5;
    return t;
}
int main()
{
   auto a3 = bar();
   A<decltype(bar())>::foo(); // reference
   A<decltype(a3)>::foo();    // value
}