【问题标题】:Arbitrary number of parameter assignment with template class带有模板类的任意数量的参数分配
【发布时间】:2017-09-15 19:44:04
【问题描述】:

我想实现一个简单的模板 ObjectPool 类。 它有一个固定大小的向量作为成员变量,这些元素在创建时默认初始化。 这已经完成并且工作正常。

问题是将新元素分配给成员向量的最佳方法是什么?

我实现了add_old_way 成员函数,它能够向ObjectPool 添加任何类型的数据,并且工作正常。 我唯一的问题是我创建了一个额外的对象,并将其传递给该函数,而在内部,我只是在分配后将其丢弃。如果我们谈论的是巨型类,那就是浪费资源。

我应该如何实现 add_new_way 函数,该函数能够接受任意参数并将它们单独分配给向量元素?

请注意,ObjectPool 是模板化的,因此任何类型的类都可以是它的类型,而不仅仅是下面示例中的 Bar 或 Matrix2x2。

我现在还没有关键字可以在互联网上查找它,如果可能的话也没有。

谢谢!

template <class T>
class ObjectPool
{
    vector<T> mObjects;

    ObjectPool() : mObjects(size)
    {
    }

    //that's what i could come up with to add an object to the object pool
    void add_old_way(const T& object)
    {
        ...
        mObjects[nextFreeIndex] = object;
        ...
    }

    //desired way of adding object
    void add_new_way(...)
    {
        mObjects[nextFreeIndex].param1 = param1;
        mObjects[nextFreeIndex].param2 = param2;
        ...
        mObjects[nextFreeIndex].paramN = paramN;
    }

};

class Bar
{
    Bar(int x, string s)
    {
        mX = x;
        mS = s;
    }

    int mX;
    string mS;
};


int main()
{
    ObjectPool<Bar> v;
    ObjectPool<Matrix2x2> v;

    //that's what i could come up with
    v.add_old_way(cBar(1,"asdf"));
    v.add_old_way(cMatrix2x2(1,2,3,4));

    //desired way of adding object
    v.add_new_way(1,"asdf");
    v.add_new_way(1,2,3,4);

}

【问题讨论】:

  • 您希望它的行为类似于来自std::vectoremplace_back
  • @Justin 我刚才查了一下,不知道。是的,类似的东西,甚至查看了源代码,但只是不明白这些任意数量的参数是如何处理和单独分配的。
  • OT:如果向量是固定大小的,std::array 呢?

标签: c++ c++11 object-pooling


【解决方案1】:

利用移动语义和完美转发使分配便宜:

template <typename... Args>
void add_new_way(Args&&... args)
{
    mObjects[nextFreeIndex] = T{std::forward<Args>(args)...};
}

Live on Coliru

由于被分配的对象是临时对象,如果被分配对象的移动赋值运算符存在,则将被调用。这将允许对象将任何昂贵的复制资源的所有权从临时对象转移到池中的对象。

要进一步阅读,请看这个问题:What are move semantics?

【讨论】:

    【解决方案2】:

    如果使用 C++11 及以上版本,要实现您的add_new_way 方法,您可以使用可变参数模板参数和转发:

    template <typename... Args>
    void add_new_way(Args... args) {
      mObjects.emplace_back(std::forward<Args>(args)...);
    }
    

    然后调用代码就可以了:

    v.add_new_way(arg1, arg2, ..., argN);
    

    【讨论】:

    • 可变参数模板和转发......永远不会知道他们这样称呼,谢谢!我查找了 && 运算符,我想我也应该使用它,所以解决方案标记转到 @Miles Budnek
    猜你喜欢
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-08-25
    相关资源
    最近更新 更多