7

In my answer here, Barry pointed out that it's better to call views::transform(&Planter::getPlants) because views::transform([](Planter const& planter){... accidentally copies.

#if 1
    auto plants = planters
        | std::views::transform([](Planter const& planter){ return planter.getPlants();})
        | std::views::join
        | std::views::common
        ;
// Plant copy constructor
// Plant copy constructor
// Plant copy constructor
// Plant copy constructor
// Plant copy constructor
#else
    auto plants = planters
        | std::views::transform(&Planter::getPlants)
        | std::views::join
        ;
#endif
// Plant copy constructor
// Plant copy constructor

Here Plant is a wrapper around int and Planter is a wrapper around std::vector<int>.

https://godbolt.org/z/dr7PM5Tvd

Tom Huntington
  • 2,260
  • 10
  • 20

1 Answers1

7

Oh I actually know this one. The deduced return type of the lambda actually decays the const ref qualifiers of getPlants.

You can fix this by declaring the return type of the lambda to be decltype(auto)

views::transform([](Planter const& planter) -> decltype(auto){...});

https://godbolt.org/z/ocK5PG1z1

Tom Huntington
  • 2,260
  • 10
  • 20