Why did C++11 remove the default value from the prototypes of std::vector’s fill constructor?

The C++98 took a prototype object, then copied it n times. By default the prototype was a default-constructed object.

The C++11 version constructs n default-constructed objects.

This eliminates n copies and replaces it with n default-constructions. In addition, it avoids constructing the prototype.

Suppose your class looks like this:

struct bulky {
  std::vector<int> v;
  bulky():v(1000) {} // 1000 ints
  bulky(bulky const&)=default;
  bulky& operator=(bulky const&)=default;

  // in C++11, avoid ever having an empty vector to maintain
  // invariants:
  bulky(bulky&& o):bulky() {
    std::swap(v, o.v);
  }
  bulky& operator=(bulky&& o) {
    std::swap(v,o.v);
    return *this;
  }
};

this is a class that always owns a buffer of 1000 ints.

if we then create a vector of bulky:

std::vector<bulky> v(2);

in C++98 this allocated 3 times 1000 integers. In C++11 this allocated only 2 times 1000 integers.

In addition, the C++98 version requires that the type be copyable. There are non-copyable types in C++11, such as std::unique_ptr<T>, and a vector of default-constructed unique pointers cannot be generated using the C++98 signature. The C++11 signature has no problem with it.

std::vector<std::unique_ptr<int>> v(100);

The above wouldn’t work if we still had the C++98 version.

Leave a Comment