1

Consider the following case: the second static_assert fails (https://gcc.godbolt.org/z/KP4zxvY7G).

#include <cstdio>
#include <type_traits>
#include <vector>

std::vector<int> generate_numbers();

int main()
{
  // Ok
  {
    std::vector<int> f = generate_numbers();
  
    auto lambda = [=] { printf("%d", (int)f.size()); };
    static_assert(std::is_nothrow_move_constructible_v<decltype(lambda)>);
  }
  
  // Not good
  {
    const std::vector<int>& f = generate_numbers();
  
    auto lambda = [=] { printf("%d", (int)f.size()); };
    static_assert(std::is_nothrow_move_constructible_v<decltype(lambda)>);
  }
}

I would expect both static_assert to pass as making a copy of a const value in my mind creates a new value which does not need to preserve the constness.

But this is not what seems to happen, which is actually problematic in generic code where one may want to rely on lifetime-extension to prevent unneeded copies:

void f(auto&& foo) { 
    const auto& result = foo(); 
    ...
}

What can be done here ? I can use C++20.

Jean-Michaël Celerier
  • 7,412
  • 3
  • 54
  • 75
  • The linked question absolutely does not answer - it states "A capture with an initializer acts as if it declares and explicitly captures a variable declared with type auto, ..." ; a variable declared with type auto removes constness which is not what happens here – Jean-Michaël Celerier Aug 07 '22 at 10:51
  • No, the dupes are useful. For example, if you just capture like `f = f` then the program will [work](https://gcc.godbolt.org/z/exv4ce8sb) but if you capture like `f` it [won't](https://gcc.godbolt.org/z/zj1cW3Yq4). – Jason Aug 07 '22 at 11:06

0 Answers0