如何让vector调用fill constructor而非initializer list构造函数?
问题说明
先看这段代码:
#include <vector> #include <iostream> using namespace std; int main() { vector<char> v1 = { size_t(0),0 }; vector<char*> v2 = { size_t(0),0 }; cout << v1.size() << endl;// 输出2 cout << v2.size() << endl;// 输出0 return 0; }
这段代码里,v1调用的是vector的初始化列表构造函数,最终容器里有两个char元素(值均为0),size为2;而v2调用的是填充构造函数(fill constructor),创建了一个包含0个char*元素的容器,size为0。
背后的原因是:
- 对于
v2,初始化列表里的第一个元素size_t(0)无法隐式转换成char*,导致初始化列表构造函数不可行,编译器只能匹配参数为(size_type, const T&)的填充构造函数; - 对于
v1,size_t(0)和0都能隐式转换成char,初始化列表构造函数是可行的,而C++标准规定列表初始化时,初始化列表构造函数的优先级高于其他构造函数,因此会被优先调用。
已知显式调用填充构造函数的方式是可行的,比如:
vector<char> v1 = vector<char>(size_t(0), 0); vector<char> v1(size_t(0), 0);
现在的问题是:有没有无需显式构造临时对象或直接指定构造函数的方式,让v1像v2那样调用填充构造函数?
答案
不存在这样的方式。
因为当使用大括号初始化({...})时,只要vector<T>的初始化列表构造函数是可行的(即列表中的所有元素都能隐式转换成T),编译器就会优先选择这个构造函数,不会考虑填充构造函数。对于vector<char>,size_t(0)和0都能转换成char,所以初始化列表构造函数必然会被选中,无法让编译器跳过它去匹配填充构造函数。
如果不想显式构造临时对象,最接近的方式是使用括号初始化而非大括号初始化:
vector<char> v1(size_t(0), 0);
这种写法直接调用填充构造函数,没有显式创建临时vector对象,只是没有使用大括号而已。
内容的提问来源于stack exchange,提问作者iouvxz
相关产品推荐
相关产品推荐

