2015-07-22 17 views
5

Ben aşağıdaki işleviBir lambda yakalama için C++ functor rvalue referansı nasıl geçilir?

template<class Function> 
void f(Function&& g) { 
    h(..., [&g](){g();}); 
} 

O bir işlevi, bir lambda veya argüman olarak bir functor kabul eden bir işlev f var var. o işlevini h çağırır İçinde hangi ı g arama ve yakalama tarafından g görevlileri tarafından yapılıyor argüman olarak bir lambda geçmek.

  1. Ben lambda yakalama alanında g veya &g geçerlerse?
  2. funktor yukarıdaki kod ile kopyalanan edilecek mi?
+1

Normalde fonksiyonu benzeri nesneler değer geçirilir. Onları kopyalamak son derece ucuz olmalı. Nesneleriniz böyle değilse, muhtemelen tamamen doğru olmayan bir şey yapıyorsunuz demektir. –

cevap

2

Eğer Snippet'inizdeki gösterilen sözdizimi &g ile, yani referans olarak g yakalamak durumunda kopya yapılacaktır. Bu tercih edilen yoldur. lambda potansiyel g atıfta nesnenin bir yıkım anlamına f bittikten sonra adlandırılabilecek, yalnızca kopyalamanız gerekir. Bu durumda
, yönlendirme olsa daha ucuz olabilir:

template<class Function> 
void f(Function&& g) { 
    h(…, [g=std::forward<Function>(g)] {g();}); 
} 
+2

Burada, 'g' orijinalinin bir kopyasını/hareketini yaptığınızı unutmayın. bakınız [mükemmel yakalama-a-mükemmel iletici evrensel referans-in-a-lambda] (http://stackoverflow.com/questions/31410209/perfectly-capturing-a-perfect-forwarder-universal-reference-in -a-lambda/31410880 # 31410880) – Jarod42

+2

@ Jarod42 Bu benim amacımdı. biri 11 – Columbo

+1

Dieter'in cevap @ bakınız. @Columbo'nun cevabı C++ 14 gerektirir. Cevabını geçerli cevap olarak aldım çünkü yapmanın yeni standart yolu. Ama cevabınızı C++ 14'e geçene kadar kullanacağım. Katkınız yardımcı oldu. – chmike

1

Hiçbir argüman kabul eder ve hiçbir şey döndüren bir lambda inşa edilmektedir. Ama zaten böyle bir eğlencenin var: g! Sadece ileri o olmalıdır:

template<class Function> 
void f(Function&& g) { 
    h(..., std::forward<Function>(g)); 
} 
+2

OP'nin bunu kısalttığından şüpheleniyorum ve gerçekte lambda daha fazlasını yapıyor. – Ishamael

+4

@Ishamael O zaman OP, OP'in ne yapmak istediğini sormalı ki tahmin etmem gerekmiyor. – Barry

+1

As @ Ishamael, kodu en basit haliyle söktüğümüzü söyledi. Lambda 'g()' den çok daha fazla şey yapar ve 'g()' argümanlara sahiptir ve bir sonuç döndürür. Sen haklısın @Barry, lambda'nın cevaplarda optimize edilmemesi için bunu açıkça yapmalıydım. – chmike

1

Bunu olabilir:

template<class Function> 
void f(Function&& g) { 
    Function f(std::move(g)); 
    int additional = 0; 
    h(..., [&f, additional](){f(additional);}); 
} 
+1

Bu cevap C++ 11 ile çalışmak yararı vardır C++ ile çalışan eşdeğer çözüm ihtiyacı varsa – chmike

+0

AFAICS, Bu şekilde, @chmikes orijinal yaklaşımına kıyasla hiçbir faydası yoktur. Her şeyden önce, 'ilerlemeniz gerektiğinde' hareket edersiniz. İkincisi, 'f' referansla yakalanır ve ömrü g'yi aşmaz, bu nedenle fiilen' f' gereksizdir. – Columbo

+0

@columbo Görünüşe göre derleyicim (4.9.2), 'f'nin referans ile geçirilmesini gerektirir. Bu kod çalışır. 'Forward' kullanmak için kullanacağı farktan emin değilim. – chmike

İlgili konular