尽管显式声明了返回类型,但对lambda的调用是不明确的
Call to lambda is ambiguous despite explicitly stating the return type
如果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;
}
});
- 尽管显式声明了返回类型,但对lambda的调用是不明确的
- 为什么重载运算符上的异常说明符'<<'不适用于任何 std::ostream 对象,但对库中定义的运算符不起作用?
- CIN >> 在较大的数字下失败,但对较小的数字有效?
- 使用pinvoke调用的简单C++.dll;对我有效,但对其他人无效
- WiFi上的原生C++webrtc客户端降低了视频质量,但对来自chrome的呼叫很好
- 使用 lambda 函数对 STL 容器进行排序
- 矢量在C++对一种方法没有反应,但对其他方法很好
- C4244对复合加法赋值的4级警告,但对和和赋值没有警告
- 为什么不允许使用=和this的lambda(但GCC接受)
- 是否存在对类型名称有效但对基本类型无效的语言构造
- 具有lambda的对的向量的下界
- 警告 ofstream 的模棱两可,但对 ostream 则不然。有什么区别?
- 如何专门化模板类方法基于类型特征?使用std::enable_if对非类函数有效,但对类方法无效
- 语句调用构造函数,但对构造函数不做任何操作——为什么它不能编译
- cc1plus:警告:命令行选项 "-Wstrict-prototypes" 对 Ada/C/ObjC 有效,但对 C++ 无效
- OpenCL结构值对CPU正确,但对GPU不正确
- 为什么非模板化函数具有相同的名称和参数但不同的返回类型是非法的?(但对模板函数合法吗?)
- 模板默认实参SFINAE对clang有歧义,但对g++很好
- 如何在lambda中对变量使用decltype而不捕获它?
- 为什么对基类的赋值有效,但对派生类的赋值是编译错误