dimanche 24 septembre 2017

Silent breaking of constructor calls after adding initializer_list constructor

Let's consider the following:

#include <iostream>
#include <initializer_list>

class Foo {
public:
    Foo(int) {
        std::cout << "with int\n";
    }
};

int main() {
    Foo a{10};  // new style initialization
    Foo b(20);  // old style initialization
}

Upon running it prints:

with int
with int

All good. Now due to new requirements I have added a constructor which takes an initializer list.

Foo(std::initializer_list<int>) {
    std::cout << "with initializer list\n";
}

Now it prints:

with initializer list
with int

So my old code Foo a{10} got silently broken. a was supposed to be initialized with an int.

I understand that the language syntax is considering {10} as a list with one item. But how can I prevent such silent breaking of old code?

  1. Is there any compiler option which will give us warning on such cases? Since this will be compiler specific I'm mostly interested with gcc. I have already tried -Wall -Wextra.
  2. If there is no such option then do we always need to use old style construction, i.e. with () Foo b(20), for other constructors and use {} only when we really meant an initializer list?

Aucun commentaire:

Enregistrer un commentaire