2016-04-01 20 views
5

Gerçekte ne tür bir std::function örneğinin içerdiğini anlamıyorum.Std :: function by-value veya (rvalue) -reference ile mi geçmeliyim?

Değere veya referansa göre iletmek daha mı etkili?

Aşağıdaki örneklerde performans etkileri nelerdir?

tarafından değeri:

rvalue-referansla
void printStats(std::function<void(const char *)> printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 

:

void printStats(std::function<void(const char *)>&& printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 
+0

Referans veya referans değerleriyle bas komutunu mu demek istediniz? Başlığınız başka bir şeyden başka bir şey söylüyor. rvalue referans ve lvalue referansı farklı çalışır. – NathanOliver

+0

Bence basit cevap, değere göre, ancak bilmediğiniz durumda: [std :: function' üzerinden şablonlar ne zaman kullanılır] (http://stackoverflow.com/questions/14677997/stdfunction-vs-template – Maikel

+0

Bir 'std :: function'un kopyalanması genellikle bir dinamik bellek ayırma gerektirir, bu nedenle biraz pahalıdır ve bu nedenle referans olarak geçirilmelidir. – nwp

cevap

5

First, std::function hedef std::reference_wrapper bir fonksiyonu işaretçi olduğu durumda ayırma önlemek için gereklidir; uygulamaları encouraged to avoid allocation for "small" targets şunlardır:

[...] f 'in hedef bir amacı, bir nesne ve bir üye işlev işaretçisi sadece bir gösterici veya referansa sahip olan, örneğin, için. bir, hedefi, bir ayırma ve hedefin bir kopyasını içerecektir büyük std::function (hedef kesilebilir duruma sahip olabilir çünkü referans sayımı, izin verilmez) kopyalama anlamına gelir

. Ancak, özel durumunuzda, işlevinizi geçici bir prvalue ile çağıracağınız için kopya seçilecektir.

Özel durumunuzda, işlevi çağırdığınız için hemen sahip olma konusunda endişelenmenize gerek yoktur; bu nedenle, bu işlevi const referansına göre almak daha iyi olacaktır. Bunu rvalue referans ile almak, bir fonksiyona varolan bir değer ya da const referansı olan bir kullanıcıya baş ağrısına neden olur; std::move'a (eski durumda) veya bir geçici geçici kopyasını oluşturmaları gerekir (ikinci durumda).

+1

"Cesaretlendirildi "gerekli" ile aynı değildir. Ayrıca, bu alıntılanan metin bir ** not ** 'dadır ve notlar normatif değildir. –

İlgili konular