6

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.

gaofeng
  • 393
  • 1
  • 3
  • 11

2 Answers2

12

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.

Nelson Vides
  • 443
  • 4
  • 11
  • This is a great answer, but Microsoft's compiler really ought to give a more helpful message, as it doesn't indicate what type(s) the initializer list is trying and failing to match. I had to switch to gcc to work that out. – John Perry Oct 10 '22 at 13:50
3

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" };
Shadi
  • 1,701
  • 2
  • 14
  • 27