You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:42:42