2017-01-14 54 views
1

我對於理解這一點很困難。我知道我的編譯器(Visual Studio)知道lambda是什麼「類型」,因爲它有時會顯示它是lambda,但是我的模板不會推導出它,auto關鍵字也不會。模板功能或自動關鍵字不能推導出Lamba類型

template <typename T> void templatedFunc(T (*funcPtr)(void)) { } 

int main() 
{ 
    templatedFunc([]() { return 6;});  // Error, no template matches argument list 

    int (*funcPtr)(void) = []() { return 6;}; 
    templatedFunc(funcPtr);     // Works fine 

    auto p = []() { return 6; }; 
    templatedFunc(p);      // Error, no template matches 

    auto p = []() -> int { return 6; }; // Trying with explicit return type 
    templatedFunc(p)      // Error, still doesn't work 
} 

我真的不明白,任何幫助都會很大。當我將鼠標懸停在變量「p」上時,它將其類型顯示爲int()。我可以使這項工作的唯一方法是通過顯式聲明的指針,如:

int (*ptr) (void) = []() { return 6;}; 

我一直得到的錯誤是:

No instance of function template matches the argument list. Argument types are lambda []int() -> int 

感謝。

回答

3

閉合對象(適當類型)有一個隱式轉換函數指針類型,但它本身不是一個函數指針。模板參數演繹不考慮隱式轉換;你擁有的東西不是與你的函數模板簽名匹配的模式。

第一個代碼示例正常工作,因爲正在提前轉換爲函數指針。

一種更好的方式來寫接受一個可調用的是隻不使用函數指針可言,但paramatrize可調用對象本身的函數模板:

template <typename T> void templatedFunc(T f) { f(); } 
+0

這是爲什麼汽車不能推斷類型的原因是什麼? – Zebrafish

+0

@TitoneMaurice:我不明白。 'auto'推導出一個類型。它可能不是你想要的類型。 –

+0

「auto p =」後的類型是一個lambda,我的編譯器告訴我這是一個lambda,我期望p是一個指向lambda的函數指針,因爲它們被轉換爲函數指針。 – Zebrafish

1

你可以強迫無國籍拉姆達與一元爲一個函數指針+,然後將匹配的功能的模板:

templatedFunc(+[]() { return 6; }); 
+0

templatedFunc(+ [](){return 6;});在Visual Studio中對我無效。有沒有關於加號實際上的信息?我找不到任何東西。 – Zebrafish

1

由此代碼生成的對象的類型:

[]() { return 6;} 

是一種說不出名稱的類(姑且稱之爲「Ftoompsk」在年輕的榮譽)

這樣的:T (*funcPtr)(void)是一個對象非常用語言來類型 - 這是一個指向函數接受無效並返回一個T.

因爲「Ftoompsk」不捕獲任何變量,它可能會被轉換爲函數指針。但是,這種轉換不會發生在模板論證扣除期間。

您可以通過書面形式強制轉換:

auto p = +[]() { return 6; }; 
templatedFunc(p); 

因爲一元加號使前參數推導的轉換。然而,這是一個可怕的黑客攻擊,在修改lambda捕獲參數的那一刻就會失敗。

採取Kerrek的建議。如圖所示重構templatedFunc。

+0

auto p = + [](){return 6; };在Visual Studio中對我無效。有什麼信息嗎?我找不到任何東西。 – Zebrafish

+0

@TitoneMaurice的信息是在C++標準。但這個網站也是一個很好的來源:http://en.cppreference.com/w/cpp/language/lambda。微軟並沒有很好地遵守標準(他們正在逐漸改進)。除非您使用VS2015或更高版本,否則我不會抱有良好標準一致性的希望。 –

+0

MSVC的lambda表達式(至少在32位中)有*四個*轉換運算符(每個調用約定一個),因此對一元'+'沒有很好的響應。 –