如何向接收boost::any_range的函数传递Boost range?
问题原因
警告产生的根源在于boost::transformed适配器返回的迭代器会生成临时double值(因为Indexer::operator()按值返回double),但你定义的Range类型要求迭代器返回引用类型(any_range的第三个模板参数默认是Value&,即使你显式指定为const double,Boost内部处理时仍尝试将其作为引用类型适配)。
当any_iterator包装这种返回临时值的迭代器时,不得不创建局部变量存储临时值,再返回该变量的引用——这就触发了"返回局部变量地址"的警告,虽然程序暂时能运行,但存在未定义行为风险。
解决方案
调整any_range的第三个模板参数(引用类型),使其匹配transformed迭代器的返回特性:不再要求返回引用,而是直接返回值类型。
修改Range的定义为以下两种方式之一即可:
方式一:使用double作为值和引用类型
using Range = boost::any_range<double, boost::random_access_traversal_tag, double>;
- 适配
std::vector<double>/std::deque<double>:这些容器的迭代器返回double&,会被隐式转换为double值传递,无风险。 - 适配
transformed范围:直接返回临时double值,无需创建局部变量,消除警告。
方式二:保留const double作为值类型
如果你需要强调值不可修改,可以将值类型设为const double,同时引用类型也设为const double(按值返回):
using Range = boost::any_range<const double, boost::random_access_traversal_tag, const double>;
这种方式同样能避免引用临时值的问题,同时保持值的不可变性。
修改后的完整代码
#include <boost/range/irange.hpp> #include <boost/range/adaptors.hpp> #include <boost/range/any_range.hpp> #include <iostream> #include <iterator> #include <vector> // 使用方式一的Range定义 using Range = boost::any_range<double, boost::random_access_traversal_tag, double>; struct Indexer { Indexer(const double param_) : param(param_) {} double operator()(const int i) const { return static_cast<double>(i) + param; } private: const double param; }; class Temp { public: void workWithAnyRange(const Range& range) { workWithAnyRangeTemplated(range); } private: template<typename R> void workWithAnyRangeTemplated(const R& r) { for (auto i : r) { std::cout << "i: " << i << std::endl; } } }; int main() { Temp temp; temp.workWithAnyRange(std::vector<double>{1,2,3}); temp.workWithAnyRange(std::deque<double>{1,2,3}); temp.workWithAnyRange(boost::irange(0, 10) | boost::adaptors::transformed(Indexer(15.0))); // 不再产生警告 return 0; }
内容的提问来源于stack exchange,提问作者mecitsari
相关产品推荐
相关产品推荐

