編輯:
這已被報告爲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編譯器錯誤,你能想到一個解決辦法嗎?
哦,我現在標準化了,謝謝指出,因爲它可能會混淆事情。儘管VS2012接受無輸入語法。 –
@Timothy:參數列表是可選的,最小的有效lambda表達式是'[] {}'。這不是問題。 – Xeo
@Xeo我知道,原來我是省略參數列表是有效的。但它引起了人們的關注,因爲它可能是錯誤的根源,所以我想我會使用人們更熟悉的語法,以免分散注意力。 –