为何函数返回可修改ranges视图会编译错误,外部代码却正常?
问题分析与解答
核心原因
问题出在JustOneType<T>()函数的返回值类型上:
- 你给这个函数声明的返回类型是
auto &,也就是非const左值引用。 - 但
myContainer | filter | transform这一串管道操作生成的是一个临时的视图对象(右值),C++不允许将非const左值引用绑定到右值上,这就是编译错误的根源。
为什么auto x能正常编译?
当你写auto x = ...时,auto会自动推导为视图的具体类型,编译器会直接把管道生成的临时视图对象**拷贝(或移动)**到x中,这个过程完全合法,不存在引用绑定的冲突问题。
修复方案
有两种常见的修复方式:
- 去掉函数返回值的引用,让函数直接返回视图对象本身:
template <typename T> auto JustOneType() { return myContainer | std::ranges::views::filter([](auto &var) { return std::holds_alternative<T>(var); }) | std::ranges::views::transform([](auto &var) -> auto & { return std::get<T>(var); }); }
这样调用JustOneType<int>()时会返回一个临时视图对象,auto y可以正常接收它。
- 如果确实需要返回引用(不过视图本身是轻量对象,通常没必要),可以将返回类型改为
const auto &——const左值引用是允许绑定到右值的:
template <typename T> const auto &JustOneType() { return myContainer | std::ranges::views::filter([](auto &var) { return std::holds_alternative<T>(var); }) | std::ranges::views::transform([](auto &var) -> auto & { return std::get<T>(var); }); }
这种方式会延长临时对象的生命周期,但视图本身开销极低,直接返回值是更常规的选择。
内容的提问来源于stack exchange,提问作者vuko_zrno
相关产品推荐
相关产品推荐

