想简化我的 std::vector push_back 使用

Posted

技术标签:

【中文标题】想简化我的 std::vector push_back 使用【英文标题】:Want to simplify my std::vector push_back usage 【发布时间】:2019-08-15 11:51:48 【问题描述】:

我开始在 c++ 中使用 std::vector 并且想知道是否有更好的方法来编写我的代码。

我尝试直接使用 push_back(本问题末尾的示例),但看起来我无法在 push_back 函数中使用类函数。

这是我要优化的主要部分:

ShopTower st_temp;
    vector<ShopTower> shopTower;
    st_temp.set("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1);
    shopTower.push_back(st_temp);
    st_temp.set("Cannon Tower", "images/tower/cannontowerBuy.png", 30, 30, 2);
    shopTower.push_back(st_temp);
    ...

和我的设置函数:

void set(string aName, string aAdr, int aH, int aW, int aNr)
            name = aName;
            adr = aAdr;
            size.set(aH,aW);
            setAtBottom(20+((aNr-1)*(aW+20)), 20);
        

为了说明清楚,size.set 是一个简单的 height=ah width=aw 函数,setAtBottom 基本相同,只是设置了从左下角开始计数的位置。

如果可能的话,我想删除 st_temp 变量并将我的代码重写为这样的:

    shopTower.push_back(set("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1));

【问题讨论】:

为了清楚起见,您应该添加 minimal reproducible example 并解释“似乎不起作用”的含义 如果您修改 ShopTower 的构造函数以获取您需要的所有参数。你可以做 shopTower.push_back(ShopTower("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1)); @rafaelgonzalez 请使用答案部分的答案。评论无法投票,您的解决方案相当不受欢迎,OP 要求优化,您建议他们创建一个不必要的实例并复制它,这远非最佳 @foreknownas_463035818 我希望我的编辑版本是规则确认 - 我实际上认为我的代码示例是最小的可重现示例,如果需要我会添加课程,但我认为因为它应该是最小的我的设置函数解释我上课的内容。我还需要发布我的班级父母,因为 shoptower : myobject 包含类 size(w,h) 和 pos(x,y)。如果它仍然不符合我将尝试再次编辑我的帖子。 您的示例仍然无法重现,因为您可以复制并编译它,但至少现在您清楚了“不工作”的含义,并且该示例足以说明原因。 【参考方案1】:

听起来你想要emplace_back。如果您还没有,则需要有一个构造函数 ShopTower::ShopTower(string aName, string aAdr, int aH, int aW, int aNr)

shopTower.emplace_back("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1);
shopTower.emplace_back("Cannon Tower", "images/tower/cannontowerBuy.png", 30, 30, 2);

【讨论】:

谢谢 - 这是完美的!【参考方案2】:

直接的方法是在ShopTower 类上创建一个构造函数,然后在push_backemplace_back - 正如已在接受的答案answer 中指出的那样。

如果出于某种原因无法选择(即,您不能或不会添加合适的构造函数) - 那么您可以创建一个工厂函数创建对象

ShopTower createShopTower(string aName, string aAdr, int aH, int aW, int aNr);

并使用任一:

shopTower.push_back(createShopTower("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1));

或使用std::move 以避免多余的副本:

shopTower.emplace_back(std::move(createShopTower("Bow Tower", "images/tower/bowtowerBuy.png", 30, 30, 1)));

【讨论】:

【参考方案3】:

如果您从 set() 函数返回(引用)您的对象,您的尝试将起作用:

ShopTower& set(/* args */) 
    /* do the setting */
    return *this;

但是在这里重用单个对象确实没有¹好处,所以每次只需 emplace_back() 一个新对象。


¹除非 ShopTower 的某些内容您没有与我们共享并且需要在所有内容中通用(问题是缺乏良好的 MCVE)。

【讨论】:

以上是关于想简化我的 std::vector push_back 使用的主要内容,如果未能解决你的问题,请参考以下文章

在多线程 C++ 程序中使用 std::vector 时应用程序崩溃

已知序列的 std::vector

将 std::map 转换为有序的 std::vector

从 std::vector 中删除前 N 个元素

如何确定`range :: view`对象和`std :: vector`之间的等价?

std::vector pop_back() 实现