尽管显式声明了返回类型,但对lambda的调用是不明确的

Call to lambda is ambiguous despite explicitly stating the return type

本文关键字:lambda 但对 调用 不明确 返回类型 声明      更新时间:2023-10-16

如果lambda的类型是可判定的(可转换为std::function(如果我错了,请纠正我(,重载函数应该同时接受这两个函数。问题是:尽管lambda类型是显式定义的,但为什么下面会出现编译错误?([&]() -> Type {}(

请注意,对于我当前的解决方案,我需要通过引用捕获,这就是为什么代码包含它的逻辑。

以下示例描述了该问题:

#include <iostream>
#include <string>    
#include <functional>
void do_some(std::function<void(int)> thing) 
{
thing(5);
}
void do_some(std::function<bool(int)> thing)
{
if (thing(10)) 
{
std::cout << "it's true!" << std::endl;
}
}
int main()
{
int local_to_be_modified = 0;
do_some(
[&](int in)
{
local_to_be_modified = in;
std::cout << "This is void-" << std::endl;
}
);
do_some(
[&](int in) -> bool
{ 
// error: call to 'do_some' is ambiguous
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}
);
}
因为返回bool的第二个lambda表达式可以隐式转换为std::function<void(int)>std::function<bool(int)>

std::function有一个转换构造函数:

template< class F >
function( F f );

此构造函数不参与重载解析,除非f对于参数类型Args是可调用的。。。和返回类型R(由于C++14(

作为可调用、的定义

以下表达式必须有效:

INVOKE<R>(f, std::declval<ArgTypes>()...)

其中INVOKE(f,t1,t2,…,tN(定义为static_cast<void>(INVOKE(f, t1, t2, ..., tN))如果R可能cv限定void,否则INVOKE(f,t1,t2,…,tN(,隐式转换为R

注意,返回bool的第二个lambda,对于std::function<void(int)>,如上所示,static_cast<void>(INVOKE(f, t1, t2, ..., tN))是一个有效的表达式(返回的bool刚刚转换为void(。然后它也可以隐式地转换为std::function<void(int)>,从而引起歧义问题。

您可以显式地将lambdastatic_cast转换为正确类型的

using FunBoolRet = std::function<bool(int)>;
do_some(static_cast<FunBoolRet >([&](int in) 
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}));

或者将lambda存储为正确的std::function<bool(int)>类型并传递给函数(如果do_some(lmda)应该被多次调用(

FunBoolRet lmda = [&](int in)
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
};    
do_some(lmda); // pass the lambda

或者按照@MaxLanghof的建议简单地从运行中的lambda 构建std::function<bool(int)>

do_some(FunBoolRet{
[&](int in) 
{
local_to_be_modified += in;
std::cout << "This is bool-" << std::endl;
return true;
}
});
相关文章: