如何编写Bar类构造函数,使vector<int>元素通过Foo(int)初始化vector<Foo>?
如何实现Bar类的构造函数,用vector的元素初始化Foo对象
嘿,这问题其实挺常见的,我们有几种简洁高效的方式来实现这个构造函数,让std::vector<int>里的每个元素都通过Foo(int)构造出对应的Foo对象,填充到Bar的data_成员里。下面分情况给你说明:
1. 最简洁的方式:利用vector的范围构造函数
因为你的Foo(int)构造函数不是explicit的,允许从int隐式转换为Foo,所以可以直接借助std::vector的范围构造函数来完成:
class Bar { public: Bar() = default; Bar(const std::vector<int>& v) : data_(v.begin(), v.end()) {} // 核心实现代码 private: std::vector<Foo> data_; };
这个构造函数会遍历传入的v的每个int元素,自动用该元素调用Foo(int)来构造Foo对象,然后把这些对象初始化到data_里,既简洁又高效,不需要额外的循环代码。
2. 手动循环构造(适合需要额外逻辑的场景)
如果之后你需要在构造每个Foo对象时添加额外处理,或者想更明确地控制构造过程,可以用emplace_back来手动循环:
class Bar { public: Bar() = default; Bar(const std::vector<int>& v) { data_.reserve(v.size()); // 提前预留内存,避免vector多次扩容带来的性能损耗 for (int num : v) { data_.emplace_back(num); // 直接在data_的内存中构造Foo对象,避免拷贝 } } private: std::vector<Foo> data_; };
emplace_back会直接把num作为参数传递给Foo的构造函数,在data_的内部内存中直接创建Foo对象,比先构造临时Foo再拷贝的方式效率更高。
3. 特殊情况:如果Foo的构造函数是explicit的
要是后续你把Foo(int)声明成了explicit Foo(int);(禁止隐式转换),那上面的范围构造就失效了,这时候可以用std::transform配合插入迭代器,或者C++20的范围特性来实现:
C++11及以后的写法
#include <algorithm> #include <iterator> class Bar { public: Bar() = default; Bar(const std::vector<int>& v) { data_.reserve(v.size()); std::transform(v.begin(), v.end(), std::back_inserter(data_), [](int num) { return Foo(num); }); // 显式构造Foo对象 } private: std::vector<Foo> data_; };
C++20更简洁的范围写法
#include <ranges> class Bar { public: Bar() = default; Bar(const std::vector<int>& v) : data_(v | std::views::transform([](int num) { return Foo(num); })) {} private: std::vector<Foo> data_; };
总的来说,第一种方法是最推荐的,只要你的Foo(int)允许隐式转换,它就是最简洁高效的实现方式。
内容的提问来源于stack exchange,提问作者stone-zeng
相关产品推荐
相关产品推荐

