This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4574. constant_wrapper<nullptr, int()> bypasses function_ref class invariant

Section: 21.3.5 [const.wrap.class], 22.10.17.6 [func.wrap.ref] Status: New Submitter: Zhihao Yuan Opened: 2026-04-27 Last modified: 2026-05-01

Priority: Not Prioritized

View all other issues in [const.wrap.class].

View all issues with New status.

Discussion:

The wording in neither 21.3.5 [const.wrap.class] nor 22.10.17.6 [func.wrap.ref] places a constraint on the 2nd template argument of constant_wrapper, so it can be anything. An interpretation of the standard text based on that can cause

function_ref fr(constant_wrapper<nullptr, int()>{});

to initialize an object of function_ref with invalid state because int() isn't a pointer or member pointer.

The example doesn't compile in libstdc++, but not due to the same reason of the following

function_ref fr(cw<(int (*)())0>);

From the error messages you can tell that the 1st example fails only at a cautious initialization placed by libstdc++, the 2nd example fails only at static_assert, and the following example

function_ref fr(constant_wrapper<nullptr, int (*)()>{});

fails at both sites, which means the 1st example bypassed the Mandates clause of the ctor.

Godbolt demo

The 2nd template argument of constant_wrapper is defaulted to decltype(X)::type, it may need to be required to be decltype(X)::type to reliably provide value.

Proposed resolution: