无constexpr构造函数时简化冗余std::array初始化方案
嘿,我完全懂你现在的麻烦——卡在C++11的限制里,还没法给Dummy加constexpr构造函数,连可变参数模板都绕不开这个坎,确实头疼。不过别慌,还有几个实用的办法能帮你把冗余的数组初始化简化掉:
1. 通用可变参数工厂函数(最推荐)
既然不能用constexpr构造,咱们可以写一个适配任意参数的工厂函数,用完美转发来适配Dummy的构造函数,这样每次初始化元素时就不用重复写Dummy{...}了:
#include <utility> // 用于std::forward template<typename... Args> Dummy make_dummy(Args&&... args) { return Dummy{std::forward<Args>(args)...}; } // 现在数组初始化就简洁多了: Dummy dummies[] = { make_dummy(1, "first", 3.14), make_dummy(2, "second", 2.71), make_dummy(3, "third", 1.41) };
这个方法既保留了类型安全,又能适配Dummy任意参数的构造函数,C++11完全支持可变参数模板和完美转发,刚好能解决你的问题。
2. 规律元素的批量生成(适合有重复模式的场景)
如果你的dummies数组元素有固定规律(比如ID递增、参数有统一模板),可以自己实现C++14才有的std::index_sequence的简化版,批量生成初始化元素:
// 先实现C++11版的索引序列 template<std::size_t... Is> struct index_sequence {}; template<std::size_t N, std::size_t... Is> struct make_index_sequence : make_index_sequence<N-1, N-1, Is...> {}; template<std::size_t... Is> struct make_index_sequence<0, Is...> : index_sequence<Is...> {}; // 批量生成Dummy的函数 template<std::size_t... Is> std::vector<Dummy> generate_dummies(index_sequence<Is...>) { // 这里可以根据规律生成参数,比如ID是Is+1,名字是"item"加数字 return {make_dummy(Is+1, "item" + std::to_string(Is+1), 1.0 + Is*0.1)...}; } // 初始化数组的方式 constexpr std::size_t DUMMY_COUNT = 5; Dummy dummies[DUMMY_COUNT]; auto dummy_vec = generate_dummies(make_index_sequence<DUMMY_COUNT>()); std::copy(dummy_vec.begin(), dummy_vec.end(), dummies);
这种方式适合元素数量多且有规律的场景,彻底避免手动写每个元素的冗余。
3. 宏(最后备选,谨慎使用)
如果上面的方法都觉得麻烦,宏可以快速减少重复代码,但要注意宏没有类型检查,容易引发隐蔽问题:
#define MAKE_DUMMY(...) Dummy{__VA_ARGS__} Dummy dummies[] = { MAKE_DUMMY(1, "foo", 3.14), MAKE_DUMMY(2, "bar", 2.71), MAKE_DUMMY(3, "baz", 1.41) };
这个方法最简单,但尽量只在临时场景用,长期维护还是优先用前面的类型安全方案。
总的来说,通用可变参数工厂函数是最平衡的选择——既简洁又安全,完全符合C++11的限制,还不用修改Dummy类的任何代码。
内容的提问来源于stack exchange,提问作者Andreas Unterweger
相关产品推荐
相关产品推荐

