2013-05-21 38 views
4

編輯:

這已被報告爲Microsoft Connect上的VS2012 C++編譯器錯誤(link)使用lambda作爲模板參數時,此編譯器錯誤是什麼?

2014年11月11日:微軟已經回覆說這個錯誤的修復應該在Visual C++的下一個主要版本中出現。


我一直在用VS2012編譯器錯誤消息我不明白掙扎,所以我下調的問題是什麼好像最低限度。

我正在創建的使用以下main.cpp VS2012:

#include <utility> 

template <typename T> 
struct A 
{ 
    T x; 
    A(A&& other) : x(std::move(other.x)) { } 
    A(T&& x) : x(std::move(x)) { } 
}; 

template <typename T> 
A<T> build(T&& x) 
{ 
    return A<T>(std::move(x)); 
} 

int main(int argc, char* argv[]) 
{ 
    auto f = []() 
    { 
     return build([](){}); //error here 
    }; 
    return 0; 
} 

最關鍵的一點是,我試圖使用lambda作爲build功能的模板類型T。該錯誤消息我得到的是:

1> main.cpp 
1>C:\test\main.cpp(21): error C2664: 'A<T>::A(A<T> &&)' : cannot convert parameter 1 from 'A<T>' to 'A<T> &&' 
1>   with 
1>   [ 
1>    T=void (__cdecl *)(void) 
1>   ] 
1>   and 
1>   [ 
1>    T=main::<lambda_c3c618d445b3cb24eede9bf304860ad7>::()::<lambda_4240e93016e3e420ff8383c9350ae130> 
1>   ] 
1>   and 
1>   [ 
1>    T=void (__cdecl *)(void) 
1>   ] 
1>   Reason: cannot convert from 'A<T>' to 'A<T>' 
1>   with 
1>   [ 
1>    T=main::<lambda_c3c618d445b3cb24eede9bf304860ad7>::()::<lambda_4240e93016e3e420ff8383c9350ae130> 
1>   ] 
1>   and 
1>   [ 
1>    T=void (__cdecl *)(void) 
1>   ] 
1>   No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

我做我的研究和查找的頁面錯誤信息(link),但我仍然無法弄清楚的問題是什麼。你能解釋一下這個編譯器錯誤嗎?


編輯

東西肯定是怪異這裏。如果我更改了main的代碼看起來像這樣:

auto f = []() 
{ 
    int* n = new int(0); 
    auto g = [=](){ return *n; }; 
    *n++; 
    return build<decltype(g)>(std::move(g)); 
}; 

我得到一個錯誤信息提示T=int (__cdecl *)(void)在呼叫建立 - 這將意味着decltype(g)是給我一個函數指針?咦?我按值捕獲指針,然後修改它 - 不應該創建一個仿函數 - 並且沒有轉換爲函數指針嗎?也許我不理解的東西。

參見相關:Lambda expressions : n3290 draft


此外,如果這是在VS2012編譯器錯誤,你能想到一個解決辦法嗎?

回答

3

我可以確認使用GCC(在linux上),這段代碼編譯得很好。 所以我會說VisualStudio似乎是錯誤的來源。

2

我沒有Windows或Visual Studio來驗證,也沒有太多關於C++ lambda函數的經驗,但是可能需要在函數中包含(儘管爲空)參數列表?即改變行21到

return build([](){}); 

這兩個版本都使用GCC編譯,但也許Visual Studio有點挑剔。

我可能會遇到的另一個問題是,您在第24行定義的lambda函數是否會生效,因爲它的返回值涉及到您在函數本身內定義的lambda函數。

+0

哦,我現在標準化了,謝謝指出,因爲它可能會混淆事情。儘管VS2012接受無輸入語法。 –

+0

@Timothy:參數列表是可選的,最小的有效lambda表達式是'[] {}'。這不是問題。 – Xeo

+0

@Xeo我知道,原來我是省略參數列表是有效的。但它引起了人們的關注,因爲它可能是錯誤的根源,所以我想我會使用人們更熟悉的語法,以免分散注意力。 –

相關問題