// 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的构造函数。但它没有根据输出结果显示出这种方式。
答案 0 :(得分:5)
最初,我希望auto会触发Class One的构造函数。但它没有根据输出结果显示出这种方式。
它确实触发了一个构造函数:复制构造函数。但你没有检测到那个†所以你没有看到任何输出。另外两种情况不构造新对象,因此肯定会更有效率。
请注意,还有第四种情况for (auto&& it : vecOnes) {...}
它将等同于您的第二种情况,也不会创建任何新对象。
†现在你已经编辑了你的问题,应该很清楚,一个案例确实构建了新对象而其他案例都没有。
答案 1 :(得分:0)
现实情况是,这取决于......
如果您有一个内置类型的向量,例如int
,那么您也可以使用auto it
,因为它很便宜来制作副本并且每次使用该值时都会保存取消引用。对于类,这将调用可能影响性能的复制构造函数。
但是,如果你的矢量包含一个类,那么一般来说,使用auto &it
或const auto &it
来节省创建对象的副本会更有效率。使用const
而不是const
没有成本优势,它只取决于您希望如何与对象进行交互。