:
int foo(std::vector<int> const& vec) {
for (int const& el : vec)
// do something...
}
すなわち
は、上記と同じです参照は実際にはコンパイラによって管理されるポインタに過ぎず、参照には逆参照が必要です。 f2
を呼び出すための
movl (%rbx), %edi ; val = *it
addq $4, %rbx ; ++it
movl %edi, 12(%rsp) ; save val on stack
call f1(int)
leaq 12(%rsp), %rdi ; load address of saved val
call f2(int const&)
注leaq
:
#include <vector>
extern void f1(int);
extern void f2(int const&);
int foo1(std::vector<int> const& v) {
for (int const& val: v) {
f1(val);
f2(val);
}
}
int foo2(std::vector<int> const& v) {
for (int val: v) {
f1(val);
f2(val);
}
}
Assembly output
foo2は
はこれを生成します。現在のベクトル値の単純なコピーを
edi
に取り込みましたが、それをスタックにプッシュして、
f2
の参照要件を満たすアドレスを取得する必要がありました。
は、しかし、他の例では、コンパイラが参照が必要でなかったことを考え出すとちょうど正しいことを行うための完全に可能である:
#include <vector>
#include <atomic>
int total;
int foo1(std::vector<int> const& v) {
for (int const& val: v) {
total += val;
}
}
int foo2(std::vector<int> const& v) {
for (int val: v) {
total += val;
}
}
both functions produce the same code
は、コンパイラが参照を排除しました。
非コンストレジスタは使用できません。しかし、2番目の例では参照がありません。引数は単にコピーされます。 – Cubic
@Cubic私はあなたが何を意味するかわからない、 'for(int&el:vec){... modify el here ...}'と言うことができます。私はあなたが関数内でconst参照を渡すかどうかを尋ねていると思います(したがって、コンテナをコピーしません)。ループ内で参照渡しをしていないときは、何からコピーしていますか? – learning
2番目のループは 'int'の代わりに' int'と宣言された 'el'を持っているので、参照の代わりにコピーを取得します。 – Cubic