[libcxx-commits] [PATCH] D109066: [libc++] Implement P1951, default arguments for pair's forwarding constructor

Richard Smith - zygoloid via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 17 12:57:29 PDT 2021


rsmith added a comment.

This is a breaking change. For example, this is valid code in C++20 and earlier but is now rejected by libc++:

  void f(const std::pair<const std::string&, std::vector<int>> x) {}
  void g() {
    f({"foo", {1, 2}});
  }

The reason is that we used to call the `pair(const string&, const vector<int>&)` constructor (the converting constructor is not usable because we can't deduce from an initializer list), which created the `string` temporary as part of the call to `f`. We now call the `pair(U&&, V&&)` constructor, which creates a `string` temporary inside the `pair` constructor, and that temporary doesn't live long enough any more.

For what it's worth, I don't think it's super important to support this code: it's relying on a very fragile selection of `pair` constructor, and I think it's working by chance rather than by design, but this is reduced from real, valid code whose build broke after this patch landed. For the sake of conformance, perhaps we should do one of these things:

1. Get this change officially blessed as a DR, or
2. Add a `!__reference_binds_to_temporary` SFINAE check to the converting constructor in at least C++20 and before, or
3. Restrict this change to C++23 and later.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109066/new/

https://reviews.llvm.org/D109066



More information about the libcxx-commits mailing list