比方说,类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)
函数的工作原理与以上两个想法中的任何一个相似吗?
答案 0 :(得分:1)
第一件事。
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
的末尾。