编辑:
这已被报告为 Microsoft Connect (link)上的 VS2012 C++ 编译器错误。
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 作为函数的模板T
类型build
。我得到的错误信息是:
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
我已经完成了研究并在页面上查找了错误消息(链接),但我仍然无法弄清楚问题所在。你能解释一下这个编译器错误吗?
编辑
这里肯定有些奇怪。如果我将代码更改main
为如下所示:
auto f = []()
{
int* n = new int(0);
auto g = [=](){ return *n; };
*n++;
return build<decltype(g)>(std::move(g));
};
我收到一条错误消息,提示T=int (__cdecl *)(void)
在 build 调用中 - 这意味着decltype(g)
给了我一个函数指针?嗯?我正在按值捕获一个指针,然后对其进行修改-它不应该创建一个仿函数-并且一个没有转换为函数指针的函数吗?也许我不明白一些事情。
参见相关:Lambda 表达式:n3290 草案
另外,如果这是VS2012 编译器中的一个错误,你能想出一个解决方法吗?