例如,
string str = "hello";
for (char c : str) { } // 1 copy
for (char& c : str) { } // 2 reference
1和2之间是否存在相对拷贝开销差异? char是1个字节。因此,在第一个for循环中,1个字节从str复制到c。在第二个循环中,它通过引用传递。这里,通过引用传递是复制指针地址(4个字节)?我想知道它是如何在内部工作的。
答案 0 :(得分:2)
C ++标准不保证这一点。但是,几乎所有普通硬件上的现代编译器都应该将两个循环转换为完全相同的代码(假设已启用优化),因为复制char或访问对它的引用的语义在机器代码级别是无关紧要的。
以下是三个主要的编译器:https://godbolt.org/g/XfRX38
volatile char x;
void fooCopy(std::string str)
{
for (char c : str) {
x = c;
}
}
void fooReference(std::string str)
{
for (char& c : str) {
x = c;
}
}
clang
将循环展开8倍,gcc
保持简单,MSVC
与gcc
具有完全相同的循环体但具有更多界限/ stack检查它周围的样板。
但是如果你专注于循环体,那么每个编译器的两个函数(忽略标签和寄存器名称)之间的机器代码完全相同。
我个人不会对内置数值类型使用const引用,因为我知道(在我使用x86的情况下)CPU会将它们保存在寄存器中并且复制它们没有开销。在每个硬件上都不一定是这样,但在这种情况下你需要自己调查一下 - 你的编译器很可能比你更了解它。