C++ Logo

std-discussion

Advanced search

inheriting initializer_list constructor fails with empty list

From: Svetlin Totev <svetli97_at_[hidden]>
Date: Mon, 27 May 2024 17:16:10 +0300
C++ allows "inheriting" constructors with a special rule for
using-declarations. It also has a special rule for constructors that take
std::initializer_list which changes the syntax for the constructor call.

These two rules don't work consistently together. The special syntax for
constructors with std::initializer_list doesn't get inherited in all cases.
In the example below the line "B b1 {};" fails to compile because it tries
to call A() instead of A{}. Technically the constructors are inherited
correctly. It's the special syntax for initializer lists that doesn't get
inherited in the edge case of empty {} brackets. But it is inherited in all
other cases.

I'm not entirely sure if this is a language issue or a compiler one as I
can't fully comprehend the C++ standard but both gcc and clang would fail
to compile this example code and give the same reason.

This language has too many special cases. Let's not have another one.
Currently, the struct C in the example code is a working workaround for the
issue.

#include<initializer_list>

struct A { A(std::initializer_list<int> il) {}; };

struct B : A { using A::A; };

struct C : A { C(std::initializer_list<int> il) : A(il) {}; };

int main()

{

    // A(); // doesn't work, as expected

    A{}; // works as expected



    A a1 {}; // ok

    A a2 {1, 2, 3}; // ok

    A a3 {5}; // ok



    B b1 {}; // calls A() instead of A{} so it fails

    B b2 {1, 2, 3}; // ok

    B b3 {5}; // ok



    C c1 {}; // ok

    C c2 {1, 2, 3}; // ok

    C c3 {5}; // ok

    return 0;

}

Received on 2024-05-27 14:16:23