首次尝试使用C lambda表达式时会出错

Getting error on first attempt to use C++ lambda expression

本文关键字:表达式 lambda 出错      更新时间:2023-10-16

我首次尝试使用C lambdas。

我的代码看起来如下:

struct ImportModeInfo
{
    CImportTransactions::ImportMode Mode;
    LPCTSTR pszDisplayName;
    CImportTransactions *(*pFactory)(LPCTSTR pszDataFile, LPCTSTR pszCsvFile, LPCTSTR pszLogFile);
};
CImportTransactions::ImportModeInfo CImportTransactions::ImportModeTable[] =
{
    { CImportTransactions::ImportMode::GasBoy, _T("GasBoy"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return new CImportGasBoyTransactions(p1, p2, p3); } },
    { CImportTransactions::ImportMode::Opw, _T("OPW/AFC"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return new CImportOpwTransactions(p1, p2, p3); } },
};

Intellisense突出显示了[启动捕获列表,给我以下错误:

more than one conversion function from "lambda []CImportGasBoyTransactions *(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)->CImportGasBoyTransactions *" to "<error-type>" applies:
function "CImportTransactions::lambda []CImportOpwTransactions *(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)->CImportOpwTransactions *::operator CImportOpwTransactions *(*)(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)() const"
function "CImportTransactions::lambda []CImportOpwTransactions *(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)->CImportOpwTransactions *::operator CImportOpwTransactions *(*)(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)() const"
function "CImportTransactions::lambda []CImportOpwTransactions *(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)->CImportOpwTransactions *::operator CImportOpwTransactions *(*)(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)() const"
function "CImportTransactions::lambda []CImportOpwTransactions *(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)->CImportOpwTransactions *::operator CImportOpwTransactions *(*)(LPCTSTR p1, LPCTSTR p2, LPCTSTR p3)() const"

我真的不明白这意味着什么。我看不到我的lambda表达式正在使用传递给它们的三个变量。确实,我分配了一个新对象,但是这再次是从lambda内部进行的。

如果我将[]更改为[=][&],则错误会消失。谁能解释为什么在这种情况下需要这些更改中的任何一个?

更新:实际上,看起来我仍然使用[&][=]遇到以下错误,或将我的LPCTSTR参数类型更改为auto。谁能看到我做错了什么?*

'initializing': cannot convert from '<lambda_4ea6e84698d4bd1ce2c6d0d3f1bf1ccc>' to 'CImportTransactions *(__cdecl *)(LPCTSTR,LPCTSTR,LPCTSTR)'

更新2:我还尝试使用如下更改lambda(请注意返回值的Typecast)。(请注意,CImportGasBoyTransactionsCImportOpwTransactions均源自CImportTransactions,所以我不明白为什么需要类型的铸件。)

CImportTransactions::ImportModeInfo CImportTransactions::ImportModeTable[] =
{
    { CImportTransactions::ImportMode::GasBoy, _T("GasBoy"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return (CImportTransactions*)new CImportGasBoyTransactions(p1, p2, p3); } },
    { CImportTransactions::ImportMode::Opw, _T("OPW/AFC"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return (CImportTransactions*)new CImportOpwTransactions(p1, p2, p3); } },
};

结果,这似乎消除了先前的错误。但是现在我收到以下错误:

致命错误C1001:编译器中发生了内部错误。
(编译器文件'f: dd vctools compiler utc src p2 p2 p2symtab.c',第7154行)
要解决此问题,请尝试简化或更改上面列出的位置附近的程序。

哦,男孩,我不是很高兴我今晚尝试了C lambdas吗?

这个答案表明它应该起作用。

致命错误C1001

您应该向Try Visual Studio 2017的Microsoft报告此错误,也许您没有更新Visual Studio 2015更新3?

最终解决了问题。

我认为问题可能是我正在返回CImportGasBoyTransactions*CImportOpwTransactions*,但是将成员键入返回CImportTransactions*。我认为这是可以的,因为这些类型源自声明的类型。但显然不是。

在返回值上执行打字消除了错误。

CImportTransactions::ImportModeInfo CImportTransactions::ImportModeTable[] =
{
    { CImportTransactions::ImportMode::GasBoy, _T("GasBoy"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return (CImportTransactions*)new CImportGasBoyTransactions(p1, p2, p3); } },
    { CImportTransactions::ImportMode::Opw, _T("OPW/AFC"), [](LPCTSTR p1, LPCTSTR p2, LPCTSTR p3) { return (CImportTransactions*)new CImportOpwTransactions(p1, p2, p3); } },
};

还可以同时将LPCTSTR更改为auto。发现大约六个变化导致编译器崩溃,并出现内部错误。也许与2015年还不足以处理Lambdas。