Consider this:
std::vector<int*> v(1, 0);
This compiles fine with VC++10 (no warnings even at max warning level). However, it doesn't compile with llvm on mac or gcc on linux, giving an error like "assigning to int* from incompatible type const int." I'm not looking for solutions -- I know the second parameter is unnecessary or that a static_cast fixes the error.
I thought zero was implicitly convertible to any pointer type. What gives? I can do the following:
int* i = 0;
int* const& ii = 0;
const int t = 0;
i = t;
I understand that the vector constructor signature takes a const T&
which when expanded for vector<int*>
becomes int* const&
correct? Can someone explain what is going on here, and whether the VC++ or non-VC++ compiler is correct?
It looks like g++ actually wrong here. See C++98 23.1.1/9:
For every sequence defined in this clause and in clause 21:
— the constructor template X(InputIterator f, InputIterator l, const Allocator& a = Allocator())
shall have the same effect as:
X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a)
if InputIterator is an integral type.
Note that InputIterator
is a template parameter to the constructor, which in this case will be int
for your example, and thus an integral type. The g++ library actually has specific code to handle all the cases where the type being stored in the vector
is integral as well and those will all work properly. In this case, only because you used 0
would the static_cast
dictated by the standard actually be legal. I tried compiling the code that the standard says should be equivalent and it compiles with g++ 4.5.
std::vector
has a nasty constructor with this signature
template <class InputIterator>
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
which, if the compiler deducts InputIterator
as int
(!) from your parameters 0
and 1
, will be a good fit but not do what we want.
I believe C++11 requires the compiler to try harder to figure out if the parameters could actually be iterators or not. In C++03 they would probably end up as size_type(1)
and int(0)
, causing your problem.
The integer literal 0 is convertible to a null pointer, but an int
with value 0 is not!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With