范围循环(auto,auto&,const auto&)在c ++ 11中更有效

时间:2016-04-01 14:36:53

标签: c++ c++11

// Example program
#include <iostream>
#include <ostream>
#include <string>
#include <vector>

class One
{
public:
    One(int age, int price)
        : m_age(age), m_price(price)
    {
        std::cout << "m_age: " << m_age << " , m_price: " << m_price << std::endl;    
    }
    One(const One&) = default;
    One& operator=(const One&) = default;

    int age() const { return m_age; }
    int price() const { return m_price; }

private:
    int m_age;
    int m_price;    
};

std::ostream& operator<<(std::ostream& os, const One& one)
{
    os << "<< m_age: " << one.age() << " , m_price: " << one.price();
    return os;    
}

int main()
{
    std::vector<One> vecOnes = {{1, 2}, {3, 4}};

    //for(auto it: vecOnes)                // case I
    //for(auto& it: vecOnes)         // case II
    for(const auto& it: vecOnes)           // case III
    {
        std::cout << it << std::endl;
    }
}

所有三种情况都输出如下相同的结果:

m_age: 1 , m_price: 2
m_age: 3 , m_price: 4
<< m_age: 1 , m_price: 2
<< m_age: 3 , m_price: 4

问题&GT;哪种情况更有效地使用auto? 最初,我希望auto会触发class One的构造函数。但它没有根据输出结果显示出这种方式。

2 个答案:

答案 0 :(得分:5)

  

最初,我希望auto会触发Class One的构造函数。但它没有根据输出结果显示出这种方式。

它确实触发了一个构造函数:复制构造函数。但你没有检测到那个所以你没有看到任何输出。另外两种情况不构造新对象,因此肯定会更有效率。

请注意,还有第四种情况for (auto&& it : vecOnes) {...}它将等同于您的第二种情况,也不会创建任何新对象。

现在你已经编辑了你的问题,应该很清楚,一个案例确实构建了新对象而其他案例都没有。

答案 1 :(得分:0)

现实情况是,这取决于......

如果您有一个内置类型的向量,例如int,那么您也可以使用auto it,因为它很便宜来制作副本并且每次使用该值时都会保存取消引用。对于类,这将调用可能影响性能的复制构造函数。

但是,如果你的矢量包含一个类,那么一般来说,使用auto &itconst auto &it来节省创建对象的副本会更有效率。使用const而不是const没有成本优势,它只取决于您希望如何与对象进行交互。