当使用lambda作为模板参数时,这个编译器错误是什么
What is this compiler error when using a lambda as a template parameter?
编辑:
据报道,这是Microsoft Connect上的VS2012 C++编译器错误(链接(。
11月。2014年11月11日:微软回应称,该漏洞的修复应该出现在Visual C++的下一个主要版本中。
我一直在处理一条我不理解的VS2012编译器错误消息,所以我把这个问题降到了最低限度。
我正在使用VS2012:构建以下main.cpp
#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:testmain.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)
,这意味着decltype(g)
正在给我一个函数指针?嗯?我正在按值捕获指针,然后对其进行修改-它不应该有来创建一个函子吗?也许我不明白什么。
参见相关内容:Lambda表达式:n3290草案
此外,如果是VS2012编译器中的一个错误,你能想出一个解决办法吗?
我可以确认,使用GCC(在linux上(,这段代码编译得很好。所以我认为VisualStudio似乎是错误的来源。
我没有Windows或Visual Studio来验证,也没有太多使用C++中lambda函数的经验,但也许您需要在函数中包含(尽管是空的(参数列表?即将线路21改为
return build([](){});
这两个版本都使用GCC进行编译,但Visual Studio可能有点挑剔。
我可能会遇到的另一个问题是,您在第24行定义的lambda函数是否会成功,因为它的返回值涉及您在函数本身内部定义的lambda函数。
我不知道这种行为是否符合标准,但对于VC++2019,错误只在选项/permission-时发生,然后在严格模式打开时发生。
尽管如此,以下是如何解决问题的方法,只需将lambda强制转换为引用类型:
template <typename FUNC>
void f(FUNC& o){}
int main()
{
f((std::function<void()>&)[](){});
// or also:
auto func = [](){};
f(func);
}
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 在使用包含冒号的类似函数的宏时,是什么导致了这种编译器差异?
- 我的设备上的 C++ 编译器版本是什么
- 处理编译器关于可能丢失数据的警告的最优雅方法是什么
- 告诉编译器我希望变量始终存储在寄存器中的正确方法是什么
- GCC,Apple LLVM和MSVC编译器的不同部分的名称是什么?
- IBM XL C/C++ 编译器中的“1587-163”是什么意思?
- 以下代码的输出是什么(答案因差异编译器而异)
- 这个编译器错误是什么意思 - "qualified-id in declaration before ‘=’ token" C++?
- 当编译器看到 std::vector<Typo> 和 std::vector<struct 拼写错误时发出的诊断之间的差异背后的理由是什么>
- 编译器在遇到提取或插入运算符时处理信息(字符串、操纵器等)的顺序是什么?
- 确定空无限循环的编译器行为的最佳方法是什么?
- 编译器中的预处理到底是什么意思
- 编译器减少 std::copy to memcpy (memmove) 的条件是什么?
- 在 C/C++ 中创建对象时编译器优化的边界是什么
- 验证给定C++编译器是否将源代码读取为 C++11 的快速简单代码是什么?
- 编译器无法识别自动,最好的替代品是什么
- 主流C++编译器中 GC 实现的时间线是什么?
- 在 c++ 中定义的预编译器的范围是什么?
- Visual Studio 2015中的编译器是什么?