假设我们在全局名称空间中声明了以下lambda:
auto Less = [](int a,int b) -> bool
{
return a < b;
}
以及以下使用此lambda的代码:
template<typename T>
struct foo
{
foo(int v){}
bool operator<(const foo<T>&) const
{
return T(1,2);
}
};
int main()
{
typedef foo<decltype(Less)> be_less;
priority_queue<be_less> data;
}
如您所见,我Less
用作struct的模板参数foo
。对于g ++ 4.9.2,此代码无法编译:
test1.cpp:13:21: error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'
return T(1,2);
^
test1.cpp:13:21: note: candidates are:
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
auto Less = [](int a,int b) -> bool
^
test1.cpp:17:14: note: candidate expects 1 argument, 2 provided
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
test1.cpp:17:14: note: candidate expects 1 argument, 2 provided
我可能会添加两个小更改来解决此问题,首先,我需要将lambda更改为:
bool Less = [](int a,int b) -> bool
{
return a < b;
}
如您所见,我只是被替换auto
为bool
,仅此修改仍然无效:
test1.cpp:13:21: error: expression list treated as compound expression in functional cast [-fpermiss
ive]
return T(1,2);
除非我添加-fpermissive
,否则我可以这样更改operator<
bool
:
bool operator<(const foo<T>&) const
{
return T((1,2));
}
注意双括号。现在,代码已编译,一切正常。
我的问题是,为什么auto Less
不起作用但又bool Less
起作用的技术原因是什么?
我相信我知道为什么第二个中需要双括号operator<
,这是为了避免编译器将其解释T(1,2)
为声明而不是调用。
谢谢你的时间
在第一个示例中,您将构建foo<T>
where [T = decltype(Less)]
。所以在这个表达
return T(1,2);
您正在尝试通过调用需要2 int
s的构造函数来构造lambda的实例,这显然不存在。这正是错误消息告诉您的内容
error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'
存在的唯一构造函数是lambda的复制和移动构造函数(从lambda表达式创建的闭包类型不是默认可构造的),编译器试图将其匹配参数,但失败
constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
candidate expects 1 argument, 2 provided
在第二种情况下,通过进行此更改
bool Less = [](int a,int b) -> bool
{
return a < b;
};
您要做的是声明一个名为的布尔变量Less
,并将其初始化为true
。
这是因为您拥有的lambda表达式是无需捕获的,这意味着它可以隐式转换为指向函数的指针,该函数采用与lambda相同的参数,operator()
并返回与原始lambda相同的类型。因此,您将lambda表达式转换为bool(*)(int,int)
。
接下来,函数指针可以隐式转换为bool
并将始终求值true
(假设它实际上指向函数的地址,在此执行)。因此Less
被初始化为true
。
现在,decltype(Less)
无非是bool
。所以在这里,您尝试将函数样式强制转换为bool
,但传入2个参数
return T(1,2);
因此错误
error: expression list treated as compound expression in functional cast
通过添加额外的括号,您将得到一个由2个子表达式组成的表达式,该表达式由逗号分隔。这将评估并丢弃第一个子表达式(1
),并返回第二个(2
)的值,然后将bool
其转换为,因此将其转换为true
。
我不太确定您要尝试如何提出解决方案,但是如果您只想定义一些比较谓词foo
,然后由调用priority_queue
,那么以下工作可能呢?
struct foo
{
foo(int v) {}
};
auto Less = [](foo const& a, foo const& b) -> bool
{
return true; // do whatever comparison you need
};
int main()
{
using my_priority_queue = std::priority_queue<foo, std::vector<foo>, decltype(Less)>;
my_priority_queue data(Less); // pass a copy of the comparator
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句