CWG Issue 1805
This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 120a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2026-05-31
1805. Conversions of array operands in conditional-expressions
Section: 7.6.16 [expr.cond] Status: CD4 Submitter: Richard Smith Date: 2013-11-02[Moved to DR at the November, 2014 meeting.]
The final bullet of 7.6.16 [expr.cond] paragraph 3, describing the attempt to convert the operands of the conditional operator to the other operand's type as part of determining the type of the result, says,
-
Otherwise (i.e., if E1 or E2 has a nonclass type, or if they both have class types but the underlying classes are not either the same or one a base class of the other): E1 can be converted to match E2 if E1 can be implicitly converted to the type that expression E2 would have if E2 were converted to a prvalue (or the type it has, if E2 is a prvalue).
The phrase “if E2 were converted to a prvalue” is problematic if E2 has an array type. For example,
struct S {
S(const char *s);
operator const char *();
};
S s;
const char *f(bool b) {
return b ? s : ""; // #1
}
One might expect that the expression in #1 would be ambiguous, since S can be converted both to and from const char*. However, the target type for the conversion of s is const char[1], not const char*, so that conversion fails and the result of the conditional-expression has type S.
It might be better to specify the target type for this trial conversion to be the type after the usual lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions instead of simply the result of converting “to a prvalue.”
Proposed resolution (February, 2014):
Change the final subbullet of 7.6.16 [expr.cond] paragraph 3 as follows:
[Editorial note: this wording was approved by CWG, but I'd suggest an editorial change to “...or if both have class types but the underlying classes are not the same and neither is a base class of the other.” —wmm]...The process for determining whether an operand expression E1 of type T1 can be converted to match an operand expression E2 of type T2 is defined as follows:
...
If E2 is a prvalue or if neither of the conversions above can be done and at least one of the operands has (possibly cv-qualified) class type:
if E1 and E2 have class type...
Otherwise (i.e., if E1 or E2 has a nonclass type, or if they both have class types but neither are the underlying classes
are not eitherthe sameornor is one a base class of the other): E1 can be converted to match E2 if E1 can be implicitly converted to the type thatexpressionE2 would haveif E2 were converted to a prvalue (or the type it has, if E2 is a prvalue)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.