It is not really a bug. The question is what could go wrong to allow the second piece of code while the first does not compile?
The issue is that while it seems obvious to you what constructor you want to call when you do:
std::vector<std::vector<int>> graph(5, 5);
it is not so clear for the compiler. In particular there are two constructor overloads that can potentially accept the arguments:
vector(size_type,const T& value = T());
template <typename InputIterator>
vector(InputIterator first, InputIterator last);
The first one requires the conversion of 5
to size_type
(which is unsigned), while the second is a perfect match, so that will be the one picked up by the compiler...
... but the compiler requires that the second overload, if the deduced type InputIterator
is integral behaves as if it was a call to:
vector(static_cast<size_type>(first),static_cast<T>(last))
What the C++03 standard effectively mandates is that the second argument is explicitly converted from the original type int
to the destination type std::vector<int>
. Because the conversion is explicit you get the error.
The C++11 standard changes the wording to use SFINAE to disable the iterator constructor if the argument is not really an input iterator, so in a C++11 compiler the code should be rejected (which is probably the reason some have claimed this to be a bug).