g++14下ranges::to()非标量类型转换错误的简化修复问询
问题分析与简洁修复方案
错误原因
views::zip(v1, v2)生成的是由std::tuple<int, int>组成的视图序列,而ranges::to<vector<Edge>>无法自动将tuple类型转换为自定义的Edge结构体,因此编译报错。
方案1:给Edge添加转换构造(最简洁)
直接让Edge支持从tuple<int, int>的转换,这样ranges::to会自动调用该构造完成类型转换,无需额外的transform视图:
#include <ranges> #include <vector> #include <tuple> using namespace std; struct Edge { int from, to; // 支持从tuple<int, int>转换为Edge Edge(const tuple<int, int>& t) : from(get<0>(t)), to(get<1>(t)) {} }; const vector<int> v1 = {1, 1}, v2 = {2, 2}; vector<Edge> v3 = views::zip(v1, v2) | ranges::to<vector<Edge>>();
如果使用C++23,还能通过结构化绑定让构造更简洁:
struct Edge { int from, to; Edge(auto&& [a, b]) : from(a), to(b) {} };
方案2:简化lambda写法(不修改Edge的情况)
如果无法修改Edge结构体,可以简化transform的lambda表达式,去掉冗余修饰:
#include <ranges> #include <vector> using namespace std; struct Edge{int from, to;}; const vector<int> v1 = {1, 1} , v2 = {2,2}; vector<Edge> v3 = views::zip(v1, v2) | views::transform([](auto&& [a,b]) { return Edge{a,b}; }) | ranges::to<vector>();
这里用auto&&的结构化绑定省去了对tuple的显式解构,代码比原写法紧凑很多。
内容的提问来源于stack exchange,提问作者Ludovic Aubert
相关产品推荐
相关产品推荐

