创建包含其他对象并传递给要添加到向量的函数的对象的不同方式之间是否存在差异

问题描述

如果我们有一个包含其他类对象向量的类

   class BigClass
    {
    private:
    vector<ClassName> vec;
    //more code
    public:
    void AddItem(const ClassName& i) {vec.push_back(i);}
    //more code
    };

而且这个类还包含其他类的对象(结构,因为它们很简单)。其中包含另一个对象。

class ClassName
{
private:
StructName obj;
//more code
public:
ClassName(const StructName &s) : obj(s) {}
ClassName(double x,double y,int i,const &OtherStruct o1,const &OtherStruct o2) 
 : obj({x,y,i,o1,o2}) {}
};

struct StructName 
{
 double x;
 double y;
 int i;
 OtherStruct o1;
 OtherStruct o2;
};

struct OtherStruct
{
  int x;
  int y;
  int z;
};

调用 AddItem 的不同选项之间有什么区别/好处/缺点吗?假设我们已经有变量 double x,const &OtherStruct o2

AddItem({x,o2}); //1
AddItem(ClassName{x,o2}); //2
AddItem(ClassName(x,o2)); //3
AddItem(StructName{x,o2}); //4
AddItem(ClassName{StructName{x,o2}}); //5
AddItem(ClassName(StructName{x,o2})); //6

解决方法

没有。所有这些只是构造 ClassName 的不同语法,但它们基本上都是一样的。然后将 ClassName 传递给 AddItem,它的构造方式完全没有区别。而这个的实现会在vector中分配更多的空间,然后将对象复制到自身中。

然而:

template<class...Us>
void AddItem(Us&&...vs) { vec.emplace_back(std::forward<Us>(vs)...);}

这有点不同,它按原样将参数传递给向量,这将分配更多空间,然后直接在其内部构造 ClassName,这可能会也可能不会节省您的 cpu 的工作制作两份您的ClassName。 (重要提示:优化器可能已经在使用您拥有的代码执行此操作,我不知道。)

这种复杂性可能不值得,因为 ClassName 看起来很容易复制。