在下面的代码中,两种版本的打印方法都会呈现第一个呼叫解散给使用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。