我尝试编译以下代码:
vector<char*> art = { "a","an","the" };
但收到的错误消息:
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
如果我将元素类型更改为" const char *",则是这样的:
vector<const char*> art = { "a","an","the" };
可以编译。有人告诉我原因吗?非常感谢。
这里有两件事。首先也是最基本的是,默认情况下,字符串文字为C 中的const
。Shadi在他的回答中给出了一个很好的链接。
第二件事是支撑初始化不能接受狭窄的转换。这在Meyers有效的现代C 书籍的第7项中很好地解释了这一点,非常适合一本。
这是类型系统的问题:当您初始化带有括号内值的容器时,例如在{ "a","an","the" };
中,该支撑的表达式被推论为类型std::initializer_lists<const char *>
,然后将其称为容器的构造函数范围。但是,请记住,字符串文字在C 中具有const char *
类型,但是您声明了向量以包含char *
类型的元素。这将意味着缩小转换const char * -> char *
,撑杆初始化不允许。因此,该构造函数被丢弃,找不到其他编译器,并且您的编译器抱怨。
原因是因为字符串文字是常数,并且它们存储在只读的内存中。为什么?
如果它适合您,则可以使用:
vector<string> art = { "a","an","the" };