使用projection编译ranges::set_intersection时出现编译错误求助
嘿,看来你在结合projection使用ranges::set_intersection时碰上个编译错误,先帮你梳理下常见的问题点和解决办法——首先你贴的代码看起来没写完,我先把你给出的片段整理出来,再逐步分析:
你的原始代码片段(注意未完成,缺少后续逻辑):
#include <algorithm> #include <ranges> #include <vector> #include <tuple> #include <generator> #include <cstdio> #include <iostream> using namespace std; struct Edge{int from, to;auto operator<=>(const Edge&) const =default;}; enum NeighborDegree{FIRST_NEIGHBOR_DEGREE,SECOND_NEIGHBOR_DEGREE,THIRD_NEIGHBOR_DEGREE}; int main() { const vector<Edge> links; vector<tuple<Edge,NeighborDegree>> // 这里代码未结束,缺少变量定义、初始化和set_intersection调用逻辑 }
结合ranges::set_intersection的使用规则,这类编译错误大概率出自这几个原因,对应解决办法如下:
输入范围未按projection规则排序
ranges::set_intersection有个硬性要求:两个输入范围必须是已排序的,而且排序规则要和你指定的比较器、projection完全匹配。如果输入范围没排序,或者排序依据和projection不一致,不仅会编译报错,就算侥幸编译通过,运行结果也会完全不符合预期。projection与比较器不匹配,或参数传递错误
如果你想基于tuple<Edge, NeighborDegree>里的Edge部分做交集,需要明确给set_intersection传递两个projection参数(分别对应两个输入范围的投影规则),同时指定基于投影后Edge类型的比较器。我给你补全一个可正常编译的示例:
#include <algorithm> #include <ranges> #include <vector> #include <tuple> #include <generator> #include <cstdio> #include <iostream> using namespace std; struct Edge{int from, to;auto operator<=>(const Edge&) const =default;}; enum NeighborDegree{FIRST_NEIGHBOR_DEGREE,SECOND_NEIGHBOR_DEGREE,THIRD_NEIGHBOR_DEGREE}; int main() { // 注意:两个输入范围必须按projection的规则(即Edge的大小)排序 vector<tuple<Edge, NeighborDegree>> range1 = { {{1,2}, FIRST_NEIGHBOR_DEGREE}, {{2,3}, SECOND_NEIGHBOR_DEGREE}, {{4,5}, THIRD_NEIGHBOR_DEGREE} }; vector<tuple<Edge, NeighborDegree>> range2 = { {{2,3}, FIRST_NEIGHBOR_DEGREE}, {{4,5}, SECOND_NEIGHBOR_DEGREE}, {{6,7}, THIRD_NEIGHBOR_DEGREE} }; vector<tuple<Edge, NeighborDegree>> result; // 正确调用方式:指定比较器、两个范围的projection ranges::set_intersection( range1, range2, back_inserter(result), // 比较投影后的Edge类型,用默认的三路比较逻辑 [](const Edge& a, const Edge& b) { return a < b; }, // 两个范围都投影到tuple的第一个元素(Edge) &tuple<Edge, NeighborDegree>::get<0>, &tuple<Edge, NeighborDegree>::get<0> ); // 输出结果验证 for (const auto& [edge, degree] : result) { cout << "匹配的Edge: " << edge.from << "->" << edge.to << endl; } }
代码不完整导致的语法错误
你贴的代码里vector<tuple<Edge,NeighborDegree>>后面没有变量名、没有初始化,也没有后续的set_intersection调用逻辑,这本身就是语法错误,先把代码补全到能体现完整调用逻辑的状态,再排查逻辑层面的问题。编译器C++版本支持问题
ranges::set_intersection是C20引入的特性,如果你用的编译器版本太旧(比如GCC 10以下、Clang 14以下),对C20 ranges的支持不完整,也会出现各种奇怪的编译错误,确保你的编译器是支持完整C++20的版本。
总结一下:先补全代码,确保输入范围按projection规则排序,正确传递比较器和projection参数,再检查编译器版本,基本上就能解决这个编译问题啦。
内容来源于stack exchange

