2855. std::throw_with_nested("string_literal")

Section: 17.9.8 [except.nested] Status: C++17 Submitter: Jonathan Wakely Opened: 2017-01-17 Last modified: 2020-09-06

Priority: 0

View all other issues in [except.nested].

View all issues with C++17 status.

Discussion:

[except.nested] says:

template <class T> [[noreturn]] void throw_with_nested(T&& t);

Let U be remove_reference_t<T>.

Requires: U shall be CopyConstructible.

This forbids std::throw_with_nested("string literal") because T gets deduced as const char(&)[15] and so U is const char[15] which is not CopyConstructible.

A throw expression decays an array argument to a pointer (7.6.18 [expr.throw] p2) and so works fine with string literals. GCC's throw_with_nested also worked fine until I added a static_assert to enforce the CopyConstructible requirement.

The same problem exists when throwing a function type, which should also decay:

#include <exception>

void f() { }

int main() {
  std::throw_with_nested(f);
}

(Note: LWG 1370 added the remove_reference, which was a step in the right direction but not far enough.)

[2017-01-27 Telecon]

Priority 0

Proposed resolution:

This wording is relative to N4618.

  1. Edit 17.9.8 [except.nested] as indicated:

    template <class T> [[noreturn]] void throw_with_nested(T&& t);
    

    -6- Let U be remove_referencedecay_t<T>.

    -7- Requires: U shall be CopyConstructible.