P3978R0 — constant_wrapper should unwrap on call and subscript
(6 items)
LEWG
This paper proposes adding unwrapping overloads of operator() and operator[] to std::constant_wrapper to address a language-induced inconsistency where call and subscript operators cannot be found via ADL or conversion, unlike other operators. When all arguments are constant_wrapper specializations, the result is wrapped; otherwise the operators unwrap and invoke the held value directly. This mirrors the behavior of std::reference_wrapper::operator() and aligns with the design principle that constant_wrapper should transparently substitute for its held value.
- §5.2, operator[] detailed specification — The detailed description of operator[] leaves both the return type and noexcept specification as 'see below' without ever resolving them, unlike operator() which resolves both to concrete expressions. [1] [1]
- §5.2, operator() and operator[] declarations — Both declarations write 'Args&&...' without naming the parameter pack, but the Returns clauses reference 'args...'. The name 'args' is never introduced in the declarations. [2]
- §3.2, paragraph following code sample #3 — The phrase 'converts the left operand to operator+ to X' contains a garbled double preposition; should read 'converts the left operand of operator+ to X'. [3]
References — Anthropic Citations API
[1]
"The expression x + 1 in line #3 finds X::operator+ via ADL and thus converts the left operand to operator+ to X, returning int(2)."
"The expression x + 1 in line #3 finds X::operator+ via ADL and thus converts the left operand to operator+ to X, returning int(2)."
[2]
chars 7456–7697
"template
constexpr see below operator[](this T, Args&&...) noexcept(see below);
-?-
Constraints: The type of T::value is not a fundamental type and no type in..."
"template
[2]
chars 7456–7749
"template
constexpr see below operator[](this T, Args&&...) noexcept(see below);
-?-
Constraints: The type of T::value is not a fundamental type and no type in..."
"template
[3]
"constexpr invoke_result_t operator()(this T, Args&&...)
noexcept(is_nothrow_invocable_v);
…
Returns: INVOKE(T::value,..."
"constexpr invoke_result_t
Summary: Proposes adding unwrapping operator() and operator[] to constant_wrapper so that a constant_wrapper of a callable or subscriptable object can be invoked or subscripted directly, forwarding to the wrapped value. Three specification and editorial defects were found.
Pipeline: Discovery (Anthropic Opus + Citations API) → Verification Gate (OpenRouter Opus) → Report Writer (OpenRouter Opus)
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.