2

I've written a convenient functor wrapper for tuple std::get. When using it with boost transformed and operator[], I get warning that I'm returning reference to local temporary object. My system: ubuntu 14.04, compilers: clang-3.5 and g++-4.8.2, boost version: 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];
}

Warning details:

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];

Adding flag -Wreturn-stack-address is not a solution since it's dangerous in bigger projects.

I noticed that deleting const keyword gets rid of warning but I don't know why and don't want to assume that functor gets only non-const ranges.

Questions: how to fix code to get rid of warning? Why deleting const gets rid of warning?

1 Answers1

3

It's true.

//
// When storing transform iterators, operator[]()
// fails because it returns by reference. Therefore
// operator()() is provided for these cases.
//

So, you should be able to fix it with

(v | boost::adaptors::transformed(tuple_get<0>{})) (0);

which returns the abstract_value_type (which is the reference only if the elements are abstract, array or function, the value_type otherwise).

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Bah, you beat me to it. – Bulletmagnet Nov 17 '14 at 12:46
  • @sehe So it is a bug to use operator[]? Why without const there is no warning? – Andrzej Pacuk Nov 17 '14 at 14:48
  • Yes. I find that hard to explain. It is, however, something described in this standards proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4221.pdf see e.g. the sample under §2.3 Universal observation which is very similar to this one. – sehe Nov 17 '14 at 15:14