繁体   English   中英

为什么第二次初始化工作而第一个由于“元素类型不匹配”而失败?

[英]Why the second initialization work while the first one fail because of the "element type does not match"?

在 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()); // ok, convert const char* to string

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

第一行使用与元素类型 (const char*) 相同类型的 initializer_list 调用构造函数。 像这样:

vector<T>(initializer_list<T> t ) {....} 

--> 好的!

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

vector<T>(const& vector<T> t) {...}

你所做的是这样的:

vector<string>(const& vector<const char*> t){..}

--> 哪个不存在!

第一行执行 复制列表初始化(参见initializer_list构造函数)。

第二行没有匹配的构造函数,因为类型不匹配(它不能调用复制构造函数)。

第三行改为使用迭代器范围构造函数,该构造函数用于构造元素并具有可行的const char*string转换以供使用。

我的问题是为什么第二次初始化工作而第一个失败

你正在构建一个东西 这不是靠魔法完成的,它只需要调用something的构造函数之一。 任何无法匹配其中一个构造函数的表达式都无法编译。


所以,让我们首先考虑

vector<const char*> articles = {"a", "an", "the"};
vector<string> words(articles);

现在,我们需要一些对这个表达式有意义的std::vector构造函数。 它们在此处列出,唯一接近匹配的是数字 5 和 6(在撰写本文时 - 它们是复制和移动构造函数)。

因为我们没有使用std::move或以其他方式直接处理右值引用,所以移动构造函数已失效,所以让我们看看复制构造函数:

vector<string>::vector<string>(const vector<string> &other);

请注意,这不是模板化以采用任何参数类型,或采用任何类型的向量:它只匹配对完全相同类型的向量的 const 引用。 即使const char *可以隐式转换为std::string ,类型vector<string>仍然与vector<const char *> 因此,没有构造函数与给定的参数类型匹配。


然后,考虑

forward_list<string> words(articles.begin(), articles.end());

此处列出std::forward_list构造函数。 注意编号 4:

template< class InputIt >
forward_list(InputIt first, InputIt last, 
             const Allocator& alloc = Allocator() );

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


现在,有几个注意事项:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM