Title
constant_wrapper<nullptr, int()> bypasses `function_ref` class invariant
Status
new
Section
[const.wrap.class] [func.wrap.ref]
Submitter
Zhihao Yuan

Created on 2026-04-27.00:00:00 last changed 2 weeks ago

Messages

Date: 2026-04-27.00:00:00

The wording in neither [const.wrap.class] nor [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.

History
Date User Action Args
2026-04-27 00:00:00admincreate