Skip to content

CWG2906 [expr.cond], [expr.const] Lvalue-to-rvalue conversion of class types disqualifies constant expressions #550

Description

@eisenwave

Reference (section label): [expr.cond], [expr.const]

Issue description

In some situations, the lvalue-to-rvalue conversion mandated by [expr.cond] paragraph 7 can apply to class types. Such lvalue-to-rvalue conversions may not be constant expressions (see [expr.const] paragraph 5, bullet 9) even though they result in a call to the copy constructor ([conv.lval] paragraph 3, bullet 2), and calling the copy constructor directly would be a constant expression.

struct S {};
S a;
constexpr S b = a;                // OK, call to implicitly-declared copy constructor
S c           = false ? S{} : a;  // OK, call to copy constructor through lvalue-to-rvalue conversion of 'a'
constexpr S d = false ? S{} : a;  // error: lvalue-to-rvalue conversion of 'a' is not a constant expression

None of MSVC, GCC, or Clang implement this behavior and permit constexpr S d = false ? S{} : a; instead.

Suggested resolution

The use of lvalue-to-rvalue conversion in [expr.cond] may be eliminated for class types.

Alternatively, update [expr.const] to permit this case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions