如何在initializer_list传入类构造前添加元素?(GCC14.2.1)
子类初始化列表追加元素及值预处理的C++实现方案
需求概述
- 父类
A通过std::initializer_list<int>初始化成员std::vector<int> m_things - 子类
B需在传入的初始化列表基础上追加固定元素,且无法使用C++26的std::views::concat特性(当前编译器为GCC14.2.1) - 需支持在元素存入
m_things前进行预处理(如变换、过滤等)
方案一:修改父类构造,提前处理元素(推荐)
通过给A新增一个接受std::vector<int>的构造函数,让子类B可以自由处理传入的初始化列表元素,再将处理后的vector传递给父类构造,避开initializer_list的不可修改限制。
代码实现
#include <vector> #include <iostream> #include <algorithm> class A { public: A(std::initializer_list<int> things) : m_things(things) {} // 新增protected构造,允许子类传递预处理后的vector protected: explicit A(const std::vector<int>& things) : m_things(things) {} public: virtual ~A() {} virtual void X() const noexcept { for(const auto& i : m_things) { std::cout << i << std::endl; } } protected: std::vector<int> m_things; }; class B : public A { public: B(std::initializer_list<int> things) : A(prepare_things(things)) {} private: static std::vector<int> prepare_things(std::initializer_list<int> input) { std::vector<int> processed(input); // 1. 追加固定元素 processed.push_back(3); processed.push_back(5); // 2. 元素预处理示例:所有元素乘以2 std::transform(processed.begin(), processed.end(), processed.begin(), [](int val) { return val * 2; }); // 可按需添加其他处理:过滤、排序、去重等 return processed; } }; int main() { A* a = new B({1,2,4}); a->X(); // 输出:2 4 8 6 10 delete a; return 0; }
方案二:不修改父类,构造后修改成员
如果无法修改A的代码,可利用m_things的protected权限,在B的构造函数体内,先通过父类构造初始化基础元素,再追加或修改元素。
代码实现
#include <vector> #include <iostream> class A { public: A(std::initializer_list<int> things) : m_things(things) {} virtual ~A() {} virtual void X() const noexcept { for(const auto& i : m_things) { std::cout << i << std::endl; } } protected: std::vector<int> m_things; }; class B : public A { public: B(std::initializer_list<int> things) : A(things) { // 追加固定元素 m_things.push_back(3); m_things.push_back(5); // 元素预处理示例:所有元素加1 for(auto& val : m_things) { val += 1; } } }; int main() { A* a = new B({1,2,4}); a->X(); // 输出:2 3 5 4 6 delete a; return 0; }
方案对比
- 方案一:提前处理元素再传递,无冗余初始化开销,代码逻辑更清晰,适用于可修改父类代码的场景
- 方案二:无需修改父类,但会先初始化父类成员再二次修改,存在轻微性能开销,适用于父类代码不可修改的场景
内容的提问来源于stack exchange,提问作者D.G. Redd
相关产品推荐
相关产品推荐

