1

I have this minimal working example:

class A {
public:
  A(int i) {}
  A(bool b) {}
};

class B {
public:
  operator int() { return 1; };
  operator bool() { return false; };
  operator A() { return A(1); }; // I added this conversion operator to remove ambiguity
};

struct S {
  A a;
};

int main() {
  B b;

  A a{b}; // this works
  S s1{.a = b}; // this also works
    
  // error: conversion from '<brace-enclosed initializer list>' to 'A' is ambiguous
  S s2{.a{b}}; // this does not work

  return 0;
}

I added the conversion operator operator A() { return A(1); }; to class B to have an exact recipe how to convert B to A. This prevents compilation errors in the two lines

  A a{b}; // this works
  S s1{.a = b}; // this also works

But the line

  S s2{.a{b}}; // this does not work

still does not compile. Why is that? I use g++ (GCC) 14.2.0.

EDIT: I tried a different compiler. In clang version 21.0.0git (https://github.com/llvm/llvm-project.git 5c3a99760274a06f8cb7e7247ce69c2fde5fbf2a) it compiles without any errors. Is this a gcc bug?

4
  • IMO yes, this is a gcc bug, it considers 2-step conversions. Commented May 27 at 5:43
  • What options do you use when building? What version of the C++ standard does the compiler use? Commented May 27 at 5:44
  • 1
    @Someprogrammerdude I don't know how to find out default standard but the situation remains unchanged with clang main.cpp -std=c++20 (no error) vs g++ main.cpp -std=c++20 (error: conversion from '<brace-enclosed initializer list>' to 'A' is ambiguous). So I think since both compilers are new, they use c++20 per default. Commented May 27 at 5:53
  • 3
    Using S s3{ b }; works. Which points to it being a bug in GCC regarding designated initializers. Commented May 27 at 6:14

1 Answer 1

0

I think this is an expected behaviour.

The initialization using designated initializer does not use or consider the conversion operator A().

It’s going to directly search for a constructor of class A which in this case is ambiguous.

You may want to do a static cast when using brace initialization.

S s2{.a{static_cast<A>(b)}};

Sign up to request clarification or add additional context in comments.

1 Comment

I think it can't be expected since clang compiler compiles this code. Thank you for trying to help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.