This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-11-05
[Adopted at the February, 2016 meeting.]
In an example like,
struct B; struct A { A(); A(B&) = delete; operator B&(); }; struct B : A {} b; B &c = true ? A() : b;the rules of 7.6.16 [expr.cond] paragraph 3 make thisambiguous:A() can be implicitly converted to the type“lvalue reference toB,” andb satisfies theconstraints to be converted to anA prvalue (it's of a typederived fromA and the cv-qualifiers are okay). Bullet 3 bullet 1is clear that we do not actually try to create anA temporaryfromb, so we don't notice that it invokes a deleted constructorand rule out that conversion.
If the deleted conversion is in the other sense, the result isunambiguous:
struct B; struct A { A(); A(B&); operator B&() = delete; }; struct B : A {} b; B &c = true ? A() : b;A() can no longer be implicitly converted to the type“lvalue reference toB”: since the declarationB&t = A(); is not well formed (it invokes a deleted function),there is no implicit conversion. So we unambiguously convert the thirdoperand to anA prvalue.
These should presumably either both be valid or both invalid.EDG and gcc call both ambiguous.
Notes from the June, 2014 meeting:
The wording should be changed to handle the convertibilitytest more like overload resolution: the conversion "exists" ifthe conversion function is declared, but is ill-formed if itwould actually be used.
Proposed resolution (October, 2015):
Add the following as a new paragraph following7.6.16 [expr.cond] paragraph 2:
Otherwise, if the second and third operand are glvaluebit-fields of the same value category and oftypescv1T andcv2T, respectively, the operands areconsidered to be of typecvT for theremainder of this section, wherecv is the unionofcv1 andcv2.
Change 7.6.16 [expr.cond] paragraph 3 as follows:
Otherwise, if the second and third operand have differenttypes and either has (possibly cv-qualified) class type, orif both are glvalues of the same value category and the sametype except for cv-qualification, an attempt is made to
convertform an implicit conversion sequence(12.2.4.2 [over.best.ics]) from each of thoseoperands to the type of the other.[Note:Properties such as access, whether an operand is abit-field, or whether a conversion function is deleted areignored for that determination. —endnote]The process for determining whether anoperand expressionE1 of typeT1 can beconverted to match an operand expressionE2 oftypeT2 is defined as follows:Attemptsare made to form an implicit conversion sequence from anoperand expressionE1 of typeT1 to atarget type related to the typeT2 of the operand expressionE2 asfollows:
IfE2 is an lvalue
:E1 canbe converted to matchE2 ifE1 can beimplicitly converted (7.3 [conv]) to thetype, the target type is “lvaluereference toT2”, subject to the constraintthat in the conversion the reference must bind directly(9.5.4 [dcl.init.ref]) to an lvalue.IfE2 is an xvalue
:E1 can beconverted to matchE2 ifE1 can beimplicitly converted to the type, the target typeis “rvalue reference toT2”,subject to the constraint that the reference must binddirectly.IfE2 is a prvalue or if neither of the
conversionsconversion sequences abovecan bedoneformed and at least one ofthe operands has (possibly cv-qualified) classtype:
ifE1 andE2 have class type,and the underlying class types are the same or one is a baseclass of the other:E1 can be converted tomatchE2 if the class ofT2 is the sametype as, or a base class of, the class ofT1, and thecv-qualification ofT2 is the same cv-qualification as, or agreater cv-qualification than, the cv-qualification ofT1. If the conversion is applied,E1 ischanged to a prvalue of typeT2 bycopy-initializing a temporary of typeT2fromE1 and using that temporary as the convertedoperand.ifT1 andT2 are thesame class type (ignoring cv-qualification), or one is abase class of the other, andT2 is at least ascv-qualified asT1, the target type isT2,
Otherwise (ifE1 orE2 has a non-classtype, or if they both have class types but the underlyingclasses are not the same and neither is a base class of theother):E1 can be converted to matchE2ifE1 can be implicitly converted tootherwise, the target type is the type thatE2 would have after applying the lvalue-to-rvalue(7.3.2 [conv.lval]), array-to-pointer(7.3.3 [conv.array]), and function-to-pointer(7.3.4 [conv.func]) standard conversions.Using this process, it is determined whetheranimplicit conversion sequence can be formed from thesecond operand
can be converted to matchto the target type determined for the thirdoperand, andwhether the third operand can be convertedto match the second operandvice versa. Ifbothcan be convertedsequences can beformed, or onecan be converted but theconversion isformed, but it is the ambiguousconversion sequence, the program is ill-formed. Ifneither can be convertedno conversionsequence can be formed, the operands are leftunchanged and further checking is performed as describedbelow.If exactly one conversion ispossible,Otherwise, if exactly one conversionsequence can be formed, that conversion is applied tothe chosen operand and the converted operand is used inplace of the original operand for the remainder of thissection.[Note: The conversion might beill-formed even if an implicit conversion sequence couldbe formed. —end note]
This resolution also resolvesissue 1932.