我为tuple std :: get编写了一个方便的函子包装器。当使用boost transformation和operator []时,我得到警告,我返回对本地临时对象的引用。我的系统:ubuntu 14.04,编译器:clang-3.5和g ++ - 4.8.2,boost版本:1.56。
#include <boost/range/adaptor/transformed.hpp>
#include <utility>
#include <vector>
template <std::size_t I>
struct tuple_get {
template <typename Tuple>
auto operator()(Tuple &&tuple) const ->
decltype(std::get<I>(std::forward<Tuple>(tuple))) {
return std::get<I>(std::forward<Tuple>(tuple));
}
};
int main() {
//removing const gets rid of warning
const std::vector<std::tuple<int,int>> v = {std::make_tuple(0, 0)};
//gives warning
(v | boost::adaptors::transformed(tuple_get<0>{})) [0];
}
警告详情:
include/boost/range/iterator_range_core.hpp:390:16: warning: returning reference to local temporary object [-Wreturn-stack-address]
return this->m_Begin[at];
note: in instantiation of member function 'boost::iterator_range_detail::iterator_range_base<boost::transform_iterator<tuple_get<0>,
std::__1::__wrap_iter<const std::__1::tuple<int, int> *>, boost::use_default, boost::use_default>, boost::random_access_traversal_tag>::operator[]' requested here
(v | boost::adaptors::transformed(tuple_get<0>{})) [0];
添加标志-Wreturn-stack-address不是解决方案,因为它在较大的项目中很危险。
我注意到删除const关键字会消除警告,但我不知道为什么,也不想假设functor只获取非const范围。
问题:如何修复代码以摆脱警告?为什么删除const会消除警告?
答案 0 :(得分:2)
这是真的。
//
// When storing transform iterators, operator[]()
// fails because it returns by reference. Therefore
// operator()() is provided for these cases.
//
所以,你应该能够用
修复它(v | boost::adaptors::transformed(tuple_get<0>{})) (0);
返回abstract_value_type
(仅当元素是抽象,数组或函数时才是引用,否则返回value_type)。