2016-09-05 3 views
0

コンテナを定数参照で渡すと、range-forループに定数参照を宣言する際にポイントがあるか、そのプロパティに自動的に固有のループ?舞台裏の参照がそのように、ポインタを用いて実装されている - const参照だけのオーバーヘッドで、int型のような些細なスカラーの場合iterable自体がconst&引数によって渡されるときにconst&引数を持つ範囲ループ用

int foo(std::vector<int> const& vec) { 
    for (int el : vec) 
     // do something... 
} 
+0

非コンストレジスタは使用できません。しかし、2番目の例では参照がありません。引数は単にコピーされます。 – Cubic

+0

@Cubic私はあなたが何を意味するかわからない、 'for(int&el:vec){... modify el here ...}'と言うことができます。私はあなたが関数内でconst参照を渡すかどうかを尋ねていると思います(したがって、コンテナをコピーしません)。ループ内で参照渡しをしていないときは、何からコピーしていますか? – learning

+0

2番目のループは 'int'の代わりに' int'と宣言された 'el'を持っているので、参照の代わりにコピーを取得します。 – Cubic

答えて

1

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

は、コンパイラが参照を排除しました。

関連する問題