提供初始值设定项列表构造函数的有效方法
Efficient way of providing an initializer list constructor
假设,一个具有以下资源的类Base
:
struct Base
{
int m_int;
bool m_flag;
float m_float;
Base() = delete; // just to see that it didn't call
Base(int a, bool b, float c): m_int(a), m_flag(b), m_float(c) {}
};
然后我有一个SubClass
,它有一个Base
类的向量作为资源。
- 经过研究,我发现使用完美的转发或转发 参考,
Base
类资源可以更有效地创建,因为它避免了对默认构造函数的不必要调用(请更正 我,如果我错了(。 - 除了转发技术,我还想有一个 初始值设定项列表构造函数,以便我可以有一个聚合 可启动
SubClass
然后我为我的SubClass
想出了以下代码。
struct SubClass
{
private:
std::vector<Base> vec;
public:
SubClass() = delete; // just to see that it didn't call
// Idea - 1
//SubClass(std::initializer_list<Base>&& all): vec(std::move(all)) {}
// Idea - 2
SubClass(std::initializer_list<Base> all): vec(all) {}
// Idea - 3 : but no more list initialization possible
template<typename ...Arg>
void addToClass(Arg&& ...args)
{
vec.emplace_back(std::forward<Arg>(args)...);
}
};
那么在main()
中,我可以有以下两种方式来更新SubClass
中的资源:
int main()
{
// possibility - 1
SubClass obj
{
{1, true, 2.0f },
{5, false, 7.0f},
{7, false, 9.0f},
{8, true, 0.0f},
};
//possibility - 2: without list initialization
/*obj.addToClass(1, true, 2.0f);
obj.addToClass(5, false, 7.0f);
obj.addToClass(7, false, 9.0f);
obj.addToClass(8, true, 0.0f);*/
return 0;
}
问题 - 1:
在上述情况下,以下哪一项是有效的或适合使用的(良好做法(?为什么?
// Idea - 1
SubClass(std::initializer_list<Base>&& all): vec(std::move(all)) {}
// Idea - 2
SubClass(std::initializer_list<Base> all): vec(all) {}
问题 - 2:
addToClass(Arg&& ...args)
函数是否与上述两个想法中的任何一个类似?
首先要做的事。
SubClass(std::initializer_list<Base>&& all): vec(std::move(all)) {}
和
SubClass(std::initializer_list<Base> all): vec(all) {}
不要做同样的事情。 第一个还需要
SubClass(std::initializer_list<Base>& all): vec(all) {}
因此,您可以使用左值std::initializer_list
初始化它(可能永远不会发生,但可能会发生(。 按值传递涵盖了这两个重载,因此编写起来更容易,并且性能也一样好(需要很多操作才能真正发挥作用(
您无法将对象移出std::initializer_list
因为标记为const
的对象
SubClass(std::initializer_list<Base>&& all): vec(std::move(all)) {}
实际上没有移动任何东西。
至于addToClass
你可以两者兼而有之。 您可以使用将单个对象扩展到类中的模板版本。 您还可以添加重载来获取std::initializer_list
以便您可以添加多个对象,例如
void addToClass(std::initializer_list<Base> all)
{
vec.insert(vec.end(), all.begin(), all.end());
}
这会将all
中的所有对象添加到vec
的末尾。
相关文章:
- 一对向量构造函数:初始值设定项列表与显式构造
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 构造函数/函数声明参数列表中的统一初始化
- 在初始化列表之外手动调用基类的构造函数
- 采用初始值设定项列表的构造函数
- 类内初始化与构造函数初始化列表的顺序
- 结构数组的构造函数错误,错误消息:没有构造函数实例与参数列表匹配
- 大括号括起来的初始值设定项列表中的短 c++ 类构造函数
- 如何在初始化列表中的构造函数之后初始化变量/对象?
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 在构造函数初始化列表中使用 std::variant
- 没有构造函数模型的实例::模型匹配参数列表
- 在c++中为链接列表创建复制构造函数/函数
- 解释了构造函数成员初始化列表
- C2436 '{ctor}':构造函数初始值设定项列表中的成员函数或嵌套类
- 不带初始值设定项的构造函数列表,其中包含带有已删除构造函数的对象
- 空向量的构造函数列表初始化
- C++ 中的构造函数列表
- 为什么初始化构造函数列表参数时会发生异常?
- 如何在类构造函数列表中初始化结构