c++ - 使用 C++20 多态 Lambda 函数时出错
问题描述
我正在尝试通过 C++ 中的 Lambda 编写一个高阶函数,并得到了这段代码。
void ProcessList::SortCol(std::string col, bool flag) {
auto CmpGenerator = [&]<typename T>
(std::function<T(const Process &itm)> func) {
return (flag? [&](const Process &a, const Process &b) {
return func(a) < func(b);}
: [&](const Process &a, const Process &b) {
return func(a) > func(b);}
);
};
std::function<bool(const Process &a, const Process &b)> cmp;
if (col == "PID") {
cmp = CmpGenerator([](const Process &itm) {
return itm.GetPid();
});
}
else if (col == "CPU") {
cmp = CmpGenerator([](const Process &itm) {
return itm.GetRatioCPU();
});
}
else if (col == "COMMAND") {
cmp = CmpGenerator([](const Process &itm) {
return itm.GetCmd();
});
}
std::sort(lst.begin(), lst.end(), cmp);
}
但是在编译时,g++ 报告调用不匹配
no match for call to ‘(ProcessList::SortCol(std::string, bool)::<lambda(std::function<T(const Process&)>)>) (ProcessList::SortCol(std::string, bool)::<lambda(const Process&)>)’
代码有什么问题?
解决方案
此示例中的主要问题是 lambda 不是std::function
. 看到这个问题。
CmpGenerator
将其参数推导出为std::function<T(Process const&)>
,但 lambda 永远不会匹配,因此推导失败。
此外,主体CmpGenerator
试图返回两个不同的 lambdas 之一——它们具有不同的类型。这些 lambda 不能相互转换,因此条件表达式将失败。但是我们也无法推断出返回类型,CmpGenerator
因为两个不同的 lambda 具有不同的类型。
我们可以从完全手动开始。std::ranges::sort
进行投影,这在这方面很有帮助:
if (col == "PID") {
if (increasing) { // <== 'flag' is not a great name
std::ranges::sort(lst, std::less(), &Process::GetPid);
} else {
std::ranges::sort(lst, std::greater(), &Process::GetPid);
}
} else if (col == "CPU") {
// ...
}
这给出了我们需要抽象的结构:我们没有生成比较对象,我们正在生成对sort
.
那是:
auto sort_by = [&](auto projection){ // <== NB: auto, not std::function
if (increasing) {
std::ranges::sort(lst, std::less(), projection);
} else {
std::ranges::sort(lst, std::greater(), projection);
}
};
if (col == "PID") {
sort_by(&Process::GetPid);
} else if (col == "CPU") {
sort_by(&Process::GetRatioCPU);
} else if (col == "COMMAND") {
sort_by(&Process::GetCmd);
}
推荐阅读
- json - 在 Marklogic 中将 XML 转换为 JSON 时丢失数据
- javascript - 如何使用 Ramda js 规范化 Api 对特定结构的响应
- javascript - 如何将对象存储在本地文件中?
- c# - 如果标记中隐藏字段值的条件(ASPX 页面)
- c++ - 查找并绘制从形状中心到最近边缘的线
- javascript - 当使用 node.js 的集合中存在值时,Firebase 返回 false 值
- python - 如何为 10 个特征添加填充特征值?
- css - 纯 CSS 无限滚动在移动设备上不起作用
- spring - 如何在 spring-data-jpa-solr 中使字段不可搜索
- vue.js - 如何获得“manifest.json”的正确图标路径?