type traitor type traitor - 2 months ago 6x
C++ Question

Transform predicate returning local variable by reference

In the following code, I am trying to copy a

, into a
. To avoid compiler warning, I am doing explicit casting inside the predicate of
instead of using
, like this

std::vector<char> buf(10, 10);
std::vector<uint8_t> u(10);
std::transform(std::begin(buf), std::end(buf), std::begin(u),
[](uint8_t val)->decltype(*std::begin(u)){
return static_cast<decltype (*std::begin(u))> (val);

For this code, I get compiler warning saying that I am trying to return a local variable
by reference.

Why is that and how can it be fixed?


The compiler is right. In the return type of your lambda:


dereferencing the iterator returned by std::vector<T>::begin() returns T& or T const& depending on the const qualification of u. Secondly, your lambda exhibits Undefined Behavior because you are returning a reference to a temporary, val.

To solve your problems, you can use std::decay_t


Which leads us to:

std::transform(std::begin(buf), std::end(buf), std::begin(u),                                 
     [](auto val)-> std::decay_t<decltype(*std::begin(u))> {
        return val;                              


If the types are implicitly convertible, you can simply do:

std::vector<uint8_t> u(std::begin(buf), std::end(buf));

or, to an already created u:

u.assign(std::begin(buf), std::end(buf));

On the other hand, for some other complex type, a plain loop isn't bad:

for(const auto& k : buf)
    u.emplace( k.converted() ); //Assuming you must call a conversion function