C++11“自动”语义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8542873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:45:26  来源:igfitidea点击:

C++11 "auto" semantics

c++c++11

提问by Alex B

When I use C++11 auto, what are the rules of type deduction with regards to whether it will resolve to a value or a reference?

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

E.g, sometimes it is clear:

例如,有时很清楚:

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

These are less clear:

这些不太清楚:

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?

回答by B?ови?

The rule is simple : it is how you declare it.

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

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

Next example proves it :

下一个例子证明了这一点:

#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
}

The output:

输出:

value
reference
value
value
reference
value

回答by Xeo

§7.1.6.4 [dcl.spec.auto] p6

§7.1.6.4 [dcl.spec.auto] p6

Once the type of a declarator-idhas been determined according to 8.3, the type of the declared variable using the declarator-idis determined from the type of its initializer using the rules for template argument deduction.

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

This means nothing else than that automodels template argument deduction during a function call.

这意味着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

Note that #1 will always copy the passed argument, no matter if you pass a reference or anything else. (Unless you specifically specify the template argument like f<int&>(intref);.)

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

回答by qqqqq

Whatever you get from right side ( of "=" ) is never a reference. More specifically the result of an expression is never a reference. In this light, note the difference between results in the example.

无论你从右侧(“=”)得到什么都不是参考。更具体地说,表达式的结果永远不是引用。有鉴于此,请注意示例中结果之间的差异。

#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
}