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.

3
  • 8
    String literals are const char*, not char*. Reason enough? Commented Apr 4, 2018 at 6:10
  • 1
    Another variant of "why can't I initialize a char* with a string literal?". Impressive. Commented Apr 4, 2018 at 6:17
  • 1
    String literals are read only, it makes sense for the language to have some way of statically asserting that you're not trying to mutate one. Commented Apr 4, 2018 at 6:43

2 Answers 2

13

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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" };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.