我正在尝试编写一个类函数,它接受boost::any_range
,这是一个双随机访问范围。我的目的是能够将任何类型的范围传递给函数,可以是std::vector
,std::deque
或boost范围。代码适用于std::vector
和std::deque
,但当我尝试使用boost范围时,它会给出警告。
我试过这个:
#include <boost/range/irange.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/any_range.hpp>
#include <iostream>
#include <iterator>
#include <vector>
using Range = boost::any_range<const double, boost::random_access_traversal_tag, const 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))); //introduces the warning
return 0;
}
我得到了以下输出:
In file included from /opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator.hpp:22:0,
from /opt/compiler-explorer/libs/boost_1_71_0/boost/range/any_range.hpp:17,
from <source>:5:
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp: In member function 'boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::reference boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::dereference() const [with WrappedIterator = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<Indexer, double>, boost::range_detail::integer_iterator<int>, boost::use_default, boost::use_default>; Reference = double; Difference = long int; Buffer = boost::any_iterator_buffer<64ul>; boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::reference = double&]':
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp:510:57: warning: function returns address of local variable [-Wreturn-local-addr]
return dereference_cast<reference>(*m_it);
^
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp:510:51: note: declared here
return dereference_cast<reference>(*m_it);
^
ASM generation compiler returned: 0
In file included from /opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator.hpp:22:0,
from /opt/compiler-explorer/libs/boost_1_71_0/boost/range/any_range.hpp:17,
from <source>:5:
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp: In member function 'boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::reference boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::dereference() const [with WrappedIterator = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<Indexer, double>, boost::range_detail::integer_iterator<int>, boost::use_default, boost::use_default>; Reference = double; Difference = long int; Buffer = boost::any_iterator_buffer<64ul>; boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::reference = double&]':
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp:510:57: warning: function returns address of local variable [-Wreturn-local-addr]
return dereference_cast<reference>(*m_it);
^
/opt/compiler-explorer/libs/boost_1_71_0/boost/range/detail/any_iterator_wrapper.hpp:510:51: note: declared here
return dereference_cast<reference>(*m_it);
^
Execution build compiler returned: 0
Program returned: 0
i: 1
i: 2
i: 3
i: 1
i: 2
i: 3
i: 15
i: 16
i: 17
i: 18
i: 19
i: 20
i: 21
i: 22
i: 23
i: 24
正如你所看到的,它输出了一些东西,但警告似乎令人担忧。如果我删除我用boost::irange
调用函数的那一行,警告就会消失。有人能帮助我解决这个问题吗?
1条答案
按热度按时间b1zrtrql1#
我有一种感觉,我搞砸了与编译器选项,因为这似乎是它的作品-user 1508716 4分钟前
不,这只是因为它包含了boost include目录,其中包含了
-isystem
而不是-I
隐藏了警告。该警告表明转换的结果-一个右值-是通过引用返回的。这相当令人惊讶,因为您请求的引用类型是
double const
。实际上,错误消息确认:注意它是如何按照你的要求确认
Reference = double
的(顶级const在C++中的函数签名中并不重要)。然而,它认为boost::range_detail::any_random_access_iterator_wrapper<WrappedIterator, Reference, Difference, Buffer>::reference = double&
,使得dereference
的实现不安全:与Boost 1.81.0相比没有问题:https://godbolt.org/z/9qfTzn15T
实际上,boost 1.74.0包含一个修复:https://godbolt.org/z/vEe118f6G
实际上,boost 1.73.0仍然存在问题:https://godbolt.org/z/EM56Pss5q
所涉及的变化似乎是
https://github.com/boostorg/range/pull/94“Fix any_range with non-reference references can cause UB”的链接