Search code examples
c++c++11constructorinitializer-list

How to write proper std::initializer_list constructor


Consider following code:

#include <iostream>
#include <vector>

struct C {
    std::vector<int> a;
    std::string b;
    bool c;
};

void printC(const C &c) {
    // ...
}

int main() {
    printC({
        { 1, 2, 3 },
        "ehlo",
        false
    });
}

This works, because compiler can generate proper constructor for me. But if I change struct C to this:

struct C {
    std::vector<int> a;
    std::string b;
    bool c;

    C() {
        c = false;
    }
};

The printC call stops working because compiler stops generating appropriate constructor. I've tried to write myself a constructor using std::initializer_list but failed.

So the question is - How to write constructor that will make the above code compile and work again?


Solution

  • I've tried to write myself a constructor using std::initializer_list but failed.

    You don't need one. You just need a c'tor taking a vector, string and boolean:

    C(std::vector<int> a, std::string b, bool c) 
      : a(std::move(a))
      , b(std::move(b))
      , c(c) {
    }
    

    Your code should now be well-formed again. Though now it incurs two move operations, while the original aggregate version could have initialized the elements of your object directly. It's something worth considering.