I tried to compile the following codes:
vector<char*> art = { "a","an","the" };
but received error message:
error C2440: 'initializing': cannot convert from 'initializer list' to 'std::vector<char *,std::allocator<_Ty>>'
1> with
1> [
1> _Ty=char *
1> ]
1> note: No constructor could take the source type, or constructor overload resolution was ambiguous
If i changed the element type to 'const char *' like this:
vector<const char*> art = { "a","an","the" };
it can be compiled.Can someone tell me the reason?Thanks a lot.
There are two things going on here. First and the most basic one, is that string literals are const
by default in C++. Shadi gave a very good link in his answer.
The second thing is that brace initialization cannot accept narrowing conversions. This is very well explained in the item 7 of Meyers' Effective Modern C++ book, very advisable one.
It's a matter of the type system: when you initialize a container with values within braces, like in { "a","an","the" };
, this braced expression is deduced to have the type std::initializer_lists<const char *>
, which then will call the container's constructor that takes an initializer list as a parameter. But, remember that string literals have type const char *
in C++, but you declared your vector to hold elements of type char *
. This will imply a narrowing conversion const char * -> char *
, which brace initialization doesn't allow. Therefore, this constructor is discarded, no other is found, and your compiler complains.
The reason is because string literals are constants and they are being stored in the read-only memory. Why?
if it suits you, you can alternatively use:
vector<string> art = { "a","an","the" };
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