当使用lambda作为模板参数时,这个编译器错误是什么

What is this compiler error when using a lambda as a template parameter?

本文关键字:编译器 是什么 错误 参数 lambda      更新时间:2023-10-16

编辑:

据报道,这是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);
}
相关文章: