为什么第二次初始化工作,而第一次初始化失败是因为;元素类型不匹配";? < C++ >将容器初始化为另一个容器的副本。

为什么第二次初始化工作,而第一次初始化失败是因为;元素类型不匹配";? < C++ >将容器初始化为另一个容器的副本。,c++,C++,新容器和原始容器中的元素类型可以不同,只要可以将我们正在复制的元素转换为我们正在初始化的容器的元素类型 例如: vector<const char*> articles = {"a", "an", "the"}; vector<string> words(articles) ; //error:element types must match forward_list<string> words(articles.begin(), articles.end()

新容器和原始容器中的元素类型可以不同,只要可以将我们正在复制的元素转换为我们正在初始化的容器的元素类型

例如:

vector<const char*> articles = {"a", "an", "the"};
vector<string> words(articles) ; //error:element types must match
forward_list<string> words(articles.begin(), articles.end()); // ok, convert const char* to string
vector articles={“a”、“an”、“the”};
矢量词(文章)//错误:元素类型必须匹配
转发列表单词(articles.begin()、articles.end());//好的,将常量字符*转换为字符串

我的问题是,为什么第二次初始化会工作,而第一次初始化会因为元素类型不匹配而失败?

第一行使用与元素类型(const char*)相同类型的初始值设定项列表调用构造函数。 大概是这样的:

vector<T>(initializer_list<T> t ) {....} 
vector<string>(const& vector<const char*> t){..}
vector(初始值设定项_list t){….}
-->好的

第二个是复制构造函数调用,它只为相同的元素类型定义

vector<T>(const& vector<T> t) {...}
vector(const&vector t){…}
你所做的是这样的:

vector<T>(initializer_list<T> t ) {....} 
vector<string>(const& vector<const char*> t){..}
vector(const&vector t){..}
-->这是不存在的

第一行执行(cfr.)

由于类型不匹配(它不能调用复制构造函数),第二行有

第三行改为使用模板来构造元素,并有一个可行的
const char*
string
转换来使用

我的问题是为什么第二次初始化有效,而第一次初始化失败

你在建造一个什么东西。这不是通过魔法实现的,它只需要调用某个东西的构造函数。任何与构造函数之一不匹配的表达式都无法编译


那么,让我们首先考虑一下

vector<const char*> articles = {"a", "an", "the"};
vector<string> words(articles);
请注意,这并不是模板化为接受任何参数类型,也不是模板化为接受任何类型的向量:它只匹配对完全相同类型向量的常量引用。即使
const char*
隐式转换为
std::string
,类型
vector
仍然与
vector
不同。因此,没有构造函数与给定的参数类型匹配


那么,考虑一下

forward_list<string> words(articles.begin(), articles.end());
首先,这是在迭代器类型上模板化的,因此传递
vector::iterator
vector::iterator
或任何东西都没有问题。其次,从
const char*
std::string
的转换足以让这个重载在被选中后实际编译


现在,请注意以下几点:

  • 您提到了
    explicit
    关键字:这只是防止将单参数构造函数用作隐式转换。但它不会影响更高的类型:即使允许将
    string::string(const char*)
    作为隐式转换,也不会使
    vector
    转换为
    vector
    。这仍然需要通过一个
    vector
    的构造函数

  • 这里我们主要讨论如何选择重载(在本例中是重载构造函数)。编译器完全有可能选择一个重载,然后仍然无法编译。例如,使用第二个迭代器范围构造函数,迭代器指向某个不兼容(甚至不能显式转换)类型


  • 是为
    std::vector
    定义的构造函数。你认为哪一个可以匹配第二个案例?哪一个可以匹配第一个?这是不是接受单个参数的构造函数是显式的,因此不允许初始化类型转换。虽然第二个使用的构造函数不是显式的,所以在这种情况下允许类型转换?实际上,我应该链接
    forward\u列表
    ctors以及vector的。。。是时候回答了。哎呀,我没有意识到“这些”是一个链接,这澄清了我的困惑,谢谢你~
    转发列表
    是一个转移视线的问题,你可以在最后一行中使用
    向量
    显示同样的行为,这正是原因。有一种复制构造只适用于相同的元素类型,还有一种迭代器范围构造可以转换元素。第二行既不是“即使const char*隐式转换为std::string”-它是。该构造函数不是显式的