2016-12-03 7 views
13

は、次のプログラムを検討:VC++ 15がラムダキャプチャに間違ったコピーコンストラクタを呼び出していますか?

#include <iostream> 
struct X { 
    X() = default; 
    X (X &) { std::cout << "non-const called" << std::endl; } 
    X (X const &) { std::cout << "const called" << std::endl; } 
    int i() const { return 7; } 
}; 

auto f() { 
    X x; 
    auto lambda = [=]() { return x.i(); }; 
    return lambda; 
} 

int main() 
{ 
    auto lambda = f(); 
    std::cout << lambda() << std::endl; 
    return 0; 
} 

VC++ 15とを、私は出力がクラン3.9で

const called 
const called 
7 

、私はここに正しいコンパイラ

non-const called 
7 

をゲット?

+1

[This](http://stackoverflow.com/questions/3772867/lambda-capture-as-const-reference)が興味深いかもしれません。あなたの質問は重複しているとは思わない:) –

+0

VCは最適化を有効にすると、RVOも適用され、結果として 'X(X const&)'への呼び出しが1つしか発生しないことに注意する価値がある。 – Oktalist

+0

@skypjack:lambdaはconstメンバーを作成していますか? http://ideone.com/RQ7OjC私はデータメンバーが必ずしもconstではなく、 'operator()'だけであると思います。 – JohnB

答えて

2

私は、clangが正しいと言います。
ラムダがxをキャプチャし、戻り値のコンストラクタが最適化されたときに、最も適したコンストラクタが1回だけ呼び出されます。
と呼ばれるnon-const の1つのみを取得するのはそのためです。


コピーエリジオンとRVOについての詳細はherehereを参照してください。

関連する問題