2016-12-03 60 views
13

aşağıdaki programı düşünün:VC++ 15, lambda yakalama için yanlış kopya oluşturucuyu çağırır?

#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 ile, ben çıkış Clang 3.9 ile

const called 
const called 
7 

, burada doğru derleyici

non-const called 
7 

olsun olsun?

+1

[This] (http://stackoverflow.com/questions/3772867/lambda-capture-as-const-reference) ilginizi çekebilir. Düz olmak için senin sorununun bir kopya olduğunu düşünmüyorum :) –

+0

Optimizasyonlar etkinleştirildiğinde, VC de RVO uygulamasına tek bir çağrıyla "X (X const &)') yol açıyor. – Oktalist

+0

@skypjack: lambdas'ın bir const üyesi oluşturduğuna emin misin? http://ideone.com/RQ7OjC Bence veri üyeleri zorunlu değildir, sadece 'operator()' dir. – JohnB

cevap

2

Clang'ın doğru olduğunu söyleyebilirim.
En uygun yapıcı, lambda x yakalandığında ve döndürülen değer için oluşturucu en iyi duruma getirildiğinde yalnızca bir kez çağrılır.
Bu nedenle, adı verilen yalnızca bir yapılandırılmamış ürünü elde edersiniz.


kopya-elision ve RVT hakkında daha detaylı bilgi için here ve here bakınız.