2012-03-28 32 views
4

考慮以下兩個片段:std :: rvalue的前鋒參考lambda?

附錄A

template<typename CalcFuncT> 
int perform_calc(CalcFuncT&& calcfunc) 
{ 
    precalc(); 
    int const calc = calcfunc(); 
    postcalc(); 
    return calc; 
} 

int main() 
{ 
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture 
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast 
} 

附件B

template<typename CalcFuncT> 
int perform_calc(CalcFuncT&& calcfunc) 
{ 
    precalc(); 
    int const calc = std::forward<CalcFuncT>(calcfunc)(); 
    postcalc(); 
    return calc; 
} 

int main() 
{ 
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture 
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast 
} 

DIFF

precalc(); 
- int const calc = calcfunc(); 
+ int const calc = std::forward<CalcFuncT>(calcfunc)(); 
    postcalc(); 

這兩段代碼的生成代碼之間有什麼區別(如果有的話)?

換句話說什麼樣的影響是的std ::前進具有以上,如果有的話?

注意這個問題不是問什麼標準::着不一般 - 只這是什麼在上述背景下嗎?

+0

[有問題的片段的來源](http://stackoverflow.com/a/7828809/636019)。我在這裏使用'std :: forward <>',因爲調用者可能不一定總是一個lambda(它可能是一個重載'operator()'的函子)。如果調用者_is_總是一個lambda,那麼使用'std :: forward <>'沒有意義。 – ildjarn 2012-03-28 23:48:57

+0

@ildjarn:你如何重載'operator()',它只能是成員函數,以區分右值'this'與左值'this'? – 2012-03-28 23:58:50

+2

它是[N2439]中引入的C++ 11的新語法(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm),通俗地稱爲「擴展移動語義到* this「。實質上,'&'和'&&'可以用作成員函數裝飾器(除了通常的'const'和'volatile')以允許基於成員的對象的右值或左值重載函數正在被調用。 – ildjarn 2012-03-29 00:01:45

回答

4

forward連鑄拉姆達對象到一個x值要求它操作員()()之前進行。拉姆達對象的運算符()()沒有合格或過載的「& &」等等forward應該沒有影響。

+1

最好避免關於仿函數的假設,比如用戶會傳遞一個lambda。儘管rvalue限定的operator()'是一個奇怪的事物(暗示一個一次函子),但例B通過允許這種情況肯定更加正確。 – Potatoswatter 2012-03-29 06:40:45