2016-05-02 46 views
4

我也讀了C++ 14 lambda表達式通用與auto參數的關係實際上是模板,所以下面是有效的C++ 14一般C++ 14個lambda表達式與模板

auto glambda = [] (auto a) { return a; }; 
cout << glambda(23); // Prints 23 
cout << glambda('A'); // Prints A 

這不與我從模板中知道的東西完全疊加......實例化點在哪裏?如果第一個呼叫實例化一個帶有int的模板,而第二個帶有char,則它存儲在glambda變量中的內容是什麼?

+0

[這次談話在2015年cppcon(https://www.youtube.com/watch?v=WXeu4fj3zOs)是非常相關的(好!)。 *「來自第一原理的Lambdas:C++的旋風之旅」* –

回答

8

這並不是說「拉姆達是一個模板」 - 這是沒有意義的,一個lambda是一個表達式。相反,由lambda表達式定義的閉包對象的類型具有由成員函數模板定義的重載函數調用運算符。所以實例化點是相應調用操作符的首次使用。

換句話說,一個拉姆達[a, &b](auto x, auto y) -> R { /* ... */ }具有類型,如:

struct __lambda 
{ 
    __lambda(const A & __a, B & __b) : a(__a), b(__b) {} 

    template <typename T1, typename T2> 
    R operator()(T1 x, T2 y) const { /* ... */ } 

private: 
    A a; 
    B & b; 
}; 
+0

「以'__'開頭的所有名稱僅僅是闡述。」可能會有用。或不;但我喜歡說清楚。除此之外:'/ * ... * /' - C++機器人對此代碼的笑臉無動於衷。 – Yakk

+0

它不應該是「A&a」成員嗎? – Wiertek

+2

@Wiertek不? lambda通過值捕獲'a',而不是通過引用。 – Yakk

4

一個通用的λ是具有稱爲operator()模板方法的編譯器生成的類型的對象。您的代碼可以與此相當的重寫:需要時

struct MyLambda { 
    template<typename T> 
    T operator() (T val) { 
     return val; 
    } 
}; 

int main() { 
    MyLambda func; 

    std::cout << func('A'); 
    std::cout << func(42); 
} 

編譯器將實例operator()

希望它幫助

+0

通用lambda不是具有模板化方法的對象,即使存在等價關係。 – skypjack

+0

那麼......據我所知,lambda是編譯器生成的類的對象。在這種情況下,該對象有一個名爲'operator()'的模板方法。 –

+6

@skypjack什麼? lambda必須是某種具有'operator()'的對象。當前標準中將'[a,&b](auto x,auto y)'轉換爲函數調用的唯一方法是使用模板並讓模板論證扣除發生。 – NathanOliver