C++20中能否创建范围视图的vector?指定转换可行性问询
问题解答
你的原代码不可行,核心问题有两个:
- 你通过
decltype推导的T绑定了第一个lambda的专属类型,而C++中每个lambda都是独一无二的类型——哪怕逻辑完全一致,循环中每次创建的lambda类型都和第一个不同,导致后续生成的transform视图类型与T不匹配,无法存入vector<T>。 - lambda使用
[&]引用捕获系数,一旦transformation_coeff被修改或生命周期结束,后续访问视图会触发未定义行为。
可行实现方案
要实现“存储延迟计算的变换视图”,关键是让所有变换的闭包类型一致,同时保证系数生命周期安全,以下是两种可靠方案:
方案一:自定义可复制函数对象
定义一个持有系数值的函数对象,确保所有变换闭包类型相同,生成的transform_view类型也统一,就能存入同一个vector:
#include <vector> #include <ranges> struct Scaler { int coeff; int operator()(int x) const { return x * coeff; } }; int main() { std::vector<std::vector<int>> original_vectors = {{1,2,3}, {4,5,6}, {7,8,9}}; std::vector<int> transformation_coeff = {2, 3, 4}; int n = original_vectors.size(); // 统一的视图类型:transform_view<vector<int>&, Scaler> using T = decltype(std::ranges::views::transform(original_vectors[0], Scaler{})); std::vector<T> transformed_vectors; for (int i = 0; i < n; ++i) { transformed_vectors.emplace_back( std::ranges::views::transform(original_vectors[i], Scaler{transformation_coeff[i]}) ); } // 遍历视图时才会实际执行乘法计算 for (auto& view : transformed_vectors) { for (int val : view) { // 使用计算后的值 } } }
方案二:用std::function包装(灵活性更高,性能略低)
如果不想自定义结构体,可通过std::function<int(int)>统一闭包类型,代价是轻微的运行时多态开销:
#include <vector> #include <ranges> #include <functional> int main() { std::vector<std::vector<int>> original_vectors = {{1,2,3}, {4,5,6}, {7,8,9}}; std::vector<int> transformation_coeff = {2, 3, 4}; int n = original_vectors.size(); // 统一的视图类型:transform_view<vector<int>&, std::function<int(int)>> using T = decltype(std::ranges::views::transform(original_vectors[0], std::function<int(int)>{})); std::vector<T> transformed_vectors; for (int i = 0; i < n; ++i) { // 值捕获系数,避免引用悬空 transformed_vectors.emplace_back( std::ranges::views::transform(original_vectors[i], [coeff = transformation_coeff[i]](int x) { return x * coeff; }) ); } }
核心注意点
- 视图是延迟计算的,只有遍历视图时才会执行乘法操作,完全符合你“避免显式转换、重复使用时按需计算”的需求,每次遍历的时间复杂度为子vector长度的O(k),无额外消耗。
- 必须保证
original_vectors的生命周期长于transformed_vectors,因为视图持有原容器的引用,原容器销毁后视图会失效。
内容的提问来源于stack exchange,提问作者Aditya Jain
相关产品推荐
相关产品推荐

