c++c++11initializer-listlist-initializationmost-vexing-parse

How to use default member initializer if `std::initializer_list` ctor exists in C++11?


Consider the following code:

#include <iostream>

struct A {
    A(int, int) {
        std::cout << "A::A(int, int)\n";
    }

    A(std::initializer_list<int>) {
        std::cout << "A::A(std::initializer_list<int>)\n";
    }
};

struct B {
    A a(1, 2); // compiler error
};

struct C {
    A a{1, 2}; // always call A::A(std::initializer_list<int>)
};

struct D {
    A a{A(1, 2)}; // always call A::A(int, int), how UgLy it is!
};

int main() {
    new B{};
    new C{};
    new D{};
}

Is there a better solution than A a{A(1, 2)};?


Solution

  • The default member initializer for the member should be a brace-or-equal-initializer. (Parentheses cannot be used since it could conflict with function declaration syntax in some situations.)

    Thus, the member can be initialized in one of the two ways:

    1. Using an equal-initializer:

      struct B {
         A a = A(1, 2);
      };
      
    2. Using the member initializer list in the constructor:

      struct B {
         A a;
         B(): a(1, 2) {}
      };