Imr*_*ran 6 c++ stl vector overload-resolution c++11
请考虑以下示例代码:
例:
void print(int n) {
cout << "element print\n";
}
void print(vector<int> vec) {
cout << "vector print\n";
}
int main() {
/* call 1 */ print(2);
/* call 2 */ print({2});
std::vector<int> v = {2};
/* call 3 */ print(v);
/* call 4 */ print( std::vector<int>{2} );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它生成以下输出:
element print
element print
vector print
vector print
Run Code Online (Sandbox Code Playgroud)
为什么print函数调用(上例中的调用2)与接受单个值的函数匹配?我在这个调用中创建了一个向量(包含单个元素),所以它与print使用向量作为输入的调用不匹配吗?
因为第一次重载在重载决策中获胜print({2});.
在这两种情况下,复制列表初始化适用于第一次过载int,
(强调我的)
否则(如果
T不是类类型),如果braced-init-list只有一个元素,并且要么T不是引用类型,要么是与元素类型兼容的引用类型,T则直接初始化(在直接列表初始化)或复制初始化(在复制列表初始化中),但不允许缩小转换.
{2}只有一个元素,它可以用来直接初始化一个int参数; 这是完全匹配.
对于第二次超载std::vector<int>,
否则,将分
T两个阶段考虑构造函数:
std::initializer_list作为唯一参数的所有构造函数,或者如果其余参数具有默认值,则作为第一个参数,将检查所有构造函数,并通过重载解析与单个参数类型进行匹配std::initializer_list
这意味着std::initializer_list<int>构造并使用构造函数的参数std::vector<int>(构造参数print).需要一个用户定义的转换(通过构造std::vector一个std::initializer_list),然后它比第一个重载更糟糕.