编译器如何在向量vs Initializer_list之间做出决定
How does the compiler decide between vector vs initializer_list?
在下面的代码中,两种版本的打印方法都会呈现第一个呼叫解散给使用initializer_list的呼叫。如果我使用initializer_list评论该定义,则该程序无缝使用向量版本。在第一种情况下,我期望编译器抱怨!
#include <iostream>
#include <vector>
using namespace std;
void print(const vector<int>& v1){
cout << "vector n";
}
void print(const initializer_list<int>& il) {
cout << "init list n";
}
int main() {
print({1,2,3,4,5});
return 0;
}
这是过载分辨率在C 中工作的方式。print
的两个版本对于超载分辨率都可行。
-
print(const vector<int>& v1)
是过载分辨率的可行函数,因为呼叫者中的输入初始化器列表{1,2,3,4,5}
隐式转换为std::vector<int>
。 -
print(const initializer_list<int>& il)
是超载分辨率的可行函数,导致呼叫者中的输入类型完全匹配。
当两个过载都播放到play时,选择print(const initializer_list<int>& il)
作为最佳的可行函数,因为它是完美的匹配,而完美的匹配在过载分辨率方面比隐式转换更优先。
过载分辨率可以通过将参数转换为a conversion序列将参数转换为参数类型所需的操作,然后根据某些规则对转换序列进行排名。
由于我们正在初始化参考文献,因此[over.ics.ref]/2适用:
当参考类型的参数不直接绑定到参数表达式时,转换序列是根据13.3.3.1将参数表达式转换为参考的基础类型所需的序列。从概念上讲,此转换序列对应于带有参数表达式的基础类型的临时性化。顶级CV资格的任何差异都取决于初始化本身,并且不构成转换。
因此,这使我们可以使用相同的转换序列规则,就像代码为:
void o_print(initializer_list<int> ol);
void o_print(vector<int> o1);
即。将非const对象作为参数而不是const引用。
现在:
根据[over.ics.list]/2,将
int
的支撑列表转换为std::initializer_list<int>
是 IDENS conversion 。(不是列表成员需要晋升或转换为int)。根据[over.ics.list]/4,将支撑列表转换为非聚集类(
std::vector<int>
这里)通过超载分辨率选择std::vector
的构造函数,并且此序列定义为A 用户定义的转换序列。
最后,我们准备现在应用排名规则。标识转换的排名高于用户定义的转换序列,因此initializer_list<int>
版本获胜。
nb。所有参考都是指C 14。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- int(c) 和 c-'0' 之间的区别。C++
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 在cuda线程之间共享大量常量数据
- 使用"std::unordereded_map"映射到"std::list"对象
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- GCC对可能有效的代码抛出init list生存期警告
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- std::list 的两个 insert() 方法签名之间的实现差异
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- 在std::list和std::vector之间进行选择
- c++中List和Map之间的性能问题
- "std::map with mutexes"与并行插入、查找、擦除之间是否有任何速度测试"libcds maps (Michael Hashmap and Split Order List)"?
- std::list.erase(itor)在Android和Win32之间存在差异