Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are vector's multi-argument constructors taking construction parameters not marked "explicit"?

I observed the following vector constructors in the Standard C++ library

explicit vector(size_type n);
vector(size_type n, const T& value, const Allocator& = Allocator());

Is there a reason why the second constructor is not marked explicit? This compiles, and makes me feel bad

void f(vector<string>);

int main() {
  f({10, "foo"});
}

While if I omit the "foo", it doesn't compile and that is what I expect when I pass a pair (compound) value of an int and a string to a function that wants a vector of strings.

like image 532
Johannes Schaub - litb Avatar asked Feb 02 '13 17:02

Johannes Schaub - litb


2 Answers

I'm wondering whether it is legitimate in the first place to expect that { ... } always represents a list of container elements when creating a temporary. This seems to be your assumption. IMO the one-argument constructor needs to be declared as explicit to avoid undesidered conversion sequences or meaningless assignments such as:

vector<int> x = 3;

On the other hand, for the two-argument version, the only way this constructor can be called when a temporary is created is with the use of curly braces, and the programmer is well aware of what he's putting in there. For instance, it is quite clear to me that 10 and "hello" are not meant to represent a list of container elements, because 10 is not a string.

If I really wanted to pass in a vector of 10 elements initialized to "hello", I would be bothered by having to write f(vector(10, "hello")) instead of just doing f({10, "hello"}).

So to sum it up: while the one-argument constructor needs to be declared as explicit, I believe this is not mandatory for the two-argument value, because not everything which is inside a pair of curly braces should be interpreted as a list of container elements.

like image 106
Andy Prowl Avatar answered Sep 30 '22 04:09

Andy Prowl


While if I omit the "foo", it doesn't compile and that is what I expect when I pass a pair (compound) value of an int and a string to a function that wants a vector of strings.

No, you don't pass a pair of int and a string but you create a vector of size 10 with content of strings like "foo". There is nothing wrong on it! I can figure some situation where it may be usefull to create a vector contains the equal strings from the beginning.

like image 31
Leo Chapiro Avatar answered Sep 30 '22 04:09

Leo Chapiro