Skip to content

Explicit constructor with default argument is in a superstate of viable/non-viable for overload resolution #77507

@eisenwave

Description

@eisenwave

https://godbolt.org/z/Gsqs1vo5P, original issue: https://stackoverflow.com/q/77788861/5740428

struct A {
  explicit A(int = 0);
  // A()= default;
} a = {};

Clang considers this ill-formed both if you comment out the second constructor uncomment it. In its current state, clang emits:

<source>:4:3: error: chosen constructor is explicit in copy-initialization
    4 | } a = {};
      |   ^   ~~
<source>:2:12: note: explicit constructor declared here
    2 |   explicit A(int = 0);
      |            ^

When uncommenting the second constructor, we get:

<source>:4:3: error: call to constructor of 'struct A' is ambiguous
    4 | } a = {};
      |   ^   ~~
<source>:2:12: note: candidate constructor
    2 |   explicit A(int = 0);
      |            ^
<source>:3:3: note: candidate constructor
    3 |   A()= default;
      |   ^

This is nonsensical. A(int) can't simultaneously

  • be viable and cause an ambiguous overload, and
  • be non-viable and cause = {} to be ill-formed when it's the only overload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions