调用std::ranges::equal比较两个范围编译失败的原因是什么?
编译错误原因
核心原因是std::ranges::equal的约束条件未被满足,具体分为两点:
std::map<int, A>的迭代器解引用后得到的元素类型为std::pair<const int, A>,而你通过std::views::transform转换得到的视图元素类型为std::pair<int, A>,二者类型不匹配,默认的相等比较运算符无法通过约束检查。- 你定义的
struct A没有显式声明相等比较运算符,尽管C++20支持隐式生成默认operator==,但MSVC的范围库约束检查逻辑无法正确识别该隐式生成的运算符,进一步导致equality_comparable_with约束不满足。
解决方法
你可以选择以下任意一种方案修复问题:
方案1:调整转换函数返回值类型
将lambda的返回值改为和map元素类型一致的std::pair<const int, A>,同时给struct A显式添加默认operator==保证兼容性:
struct A { int x; bool operator==(const A&) const = default; }; auto v2m = [](const A& a) { return std::pair<const int, A>(a.x, a); };
方案2:传入自定义比较谓词
给std::ranges::equal显式指定比较逻辑,跳过默认的类型匹配约束:
bool equals = std::ranges::equal(actual, expected, [](const std::pair<int, A>& a, const std::pair<const int, A>& b) { return a.first == b.first && a.second.x == b.second.x; });
方案3:提取值视图比较
你也可以只比较两个范围中的A对象本身,避免pair类型不匹配的问题,该方案同样需要给struct A显式添加默认operator==:
bool equals = std::ranges::equal(actual | std::views::values, expected | std::views::values);
内容的提问来源于stack exchange,提问作者Dmitriano
相关产品推荐
相关产品推荐

