Unexpected behavior of boost::adaptors::transformed when the transformation function returns by value

117 views Asked by At

Consider the following piece of C++11 code which is the smallest reproducer I could come up with:

#include <iostream>
#include <boost/range/adaptor/transformed.hpp>

std::vector<uint32_t> myTransform(const std::vector<uint32_t>& iVector) {
  return iVector;
}

int main() {
  const std::vector<std::vector<uint32_t>> theInput{{1, 2}};
  const auto myRange = theInput | boost::adaptors::transformed(myTransform);

  for (auto it = boost::begin(myRange); it != boost::end(myRange); ++it) {
    for (auto it2 = boost::begin(*it); it2 != boost::end(*it); ++it2) {
      std::cout << *it2 << std::endl;
    }
  }
}

I expected it to print the following output:

1
2

... but instead it prints (cf http://cpp.sh/8yivt):

0
0

However, if I change myTransform to return a reference like this:

const std::vector<uint32_t>& myTransform(const std::vector<uint32_t>& iVector) {
  return iVector;
}

... then I get the expected output (cf http://cpp.sh/5brvl).

I couldn't find any explanation for this behavior from the Boost.Range documentation. Is my code incorrect ? Are my expectations incorrect ? Is it a bug/known limitation in Boost.Range ?

The aim of this question is first and foremost to understand why this behaves in an unexpected way, and only incidentally to find a solution.

0

There are 0 answers