nonesuch
is insufficiently uselessSection: 3.4 [fund.ts.v3::meta] Status: C++23 Submitter: Tim Song Opened: 2017-05-08 Last modified: 2023-11-22
Priority: 2
View all issues with C++23 status.
Discussion:
Addresses: fund.ts.v3
The definition of std::experimental::nonesuch
(with a deleted default
constructor, destructor, copy constructor, and copy assignment
operator) means that it is an aggregate, which means that it can be
initialized from {}
in contexts where the availability of the
destructor is not considered (e.g., overload resolution or a
new-expression).
struct such {}; void f(const such&); void f(const nonesuch&); f({});
For a real-life example of such ambiguity, see
GCC bug 79141,
involving libstdc++'s internal __nonesuch
type defined just like the
one in the fundamentals TS.
nonesuch
would be substantially more useful if the ICS
from {}
is gone. nonesuch
should have no default constructor (rather
than a deleted one), and it shouldn't be an aggregate.
[2017-11-20 Priority set to 2 after discussion on the reflector.]
Previous resolution [SUPERSEDED]:
This wording is relative to N4617.
Edit 99 [fund.ts.v3::meta.type.synop] as indicated, moving the definition of
nonesuch
to 3.4.3 [fund.ts.v3::meta.detect]://3.4.3 [fund.ts.v3::meta.detect], Detection idiom […] struct nonesuch{ nonesuch() = delete; ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; }; […]
Insert at the beginning of 3.4.3 [fund.ts.v3::meta.detect] the following paragraphs:
[Drafting note: The seemingly redundant statement about default and initializer-list constructors is intended to negate the usual leeway for implementations to declare additional member function signatures granted in 16.4.6.5 [member.functions]. — end drafting note]
struct nonesuch { ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; };-?-
nonesuch
has no default constructor (C++14 §[class.ctor]) or initializer-list constructor (C++14 §[dcl.init.list]), and is not an aggregate (C++14 §[dcl.init.aggr]).
[2018-08-23 Batavia Issues processing]
Change C++14 references to C++17, and all the LFTS2 references to LFTS3
Status to Tentatively Ready
[2018-11, Adopted in San Diego]
Proposed resolution:
This wording is relative to N4617.
Edit 99 [fund.ts.v3::meta.type.synop] as indicated, moving the definition of
nonesuch
to 3.4.3 [fund.ts.v3::meta.detect]:
//3.4.3 [fund.ts.v3::meta.detect], Detection idiom […] struct nonesuch{ nonesuch() = delete; ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; }; […]
Insert at the beginning of 3.4.3 [fund.ts.v3::meta.detect] the following paragraphs:
[Drafting note: The seemingly redundant statement about default and initializer-list constructors is intended to negate the usual leeway for implementations to declare additional member function signatures granted in 16.4.6.5 [member.functions]. — end drafting note]
struct nonesuch { ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; };-?-
nonesuch
has no default constructor (C++17 §[class.ctor]) or initializer-list constructor (C++17 §[dcl.init.list]), and is not an aggregate (C++17 §[dcl.init.aggr]).