任意数量的带模板的参数赋值class
Arbitrary number of parameter assignment with template class
我想实现一个 class 类的简单模板 ObjectPool。
它有一个固定大小的向量作为成员变量,这些元素在创建时默认初始化。
这已经完成并且工作正常。
问题是将新元素分配给成员向量的最佳方法是什么?
我实现了 add_old_way 成员函数,它能够将任何类型的数据添加到 ObjectPool,并且工作正常。
我唯一的问题是我创建了一个额外的对象,我将其传递给该函数,在内部,我只是在分配后将其丢弃。浪费资源,如果我们谈论的是巨大的classes。
我应该如何实现 add_new_way 能够获取任意参数并将它们单独分配给向量元素的函数?
请注意 ObjectPool 是模板化的,因此任何类型的 class 都可以是它的类型,而不仅仅是下例中的 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);
}
如果使用 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);
利用移动语义和完美转发来降低分配成本:
template <typename... Args>
void add_new_way(Args&&... args)
{
mObjects[nextFreeIndex] = T{std::forward<Args>(args)...};
}
由于被赋值的对象是临时的,如果被赋值对象的移动赋值运算符存在,将被调用。这将使对象将任何昂贵的复制资源的所有权从临时资源转移到池中的对象。
如需进一步阅读,请查看此问题:What are move semantics?
我想实现一个 class 类的简单模板 ObjectPool。 它有一个固定大小的向量作为成员变量,这些元素在创建时默认初始化。 这已经完成并且工作正常。
问题是将新元素分配给成员向量的最佳方法是什么?
我实现了 add_old_way 成员函数,它能够将任何类型的数据添加到 ObjectPool,并且工作正常。 我唯一的问题是我创建了一个额外的对象,我将其传递给该函数,在内部,我只是在分配后将其丢弃。浪费资源,如果我们谈论的是巨大的classes。
我应该如何实现 add_new_way 能够获取任意参数并将它们单独分配给向量元素的函数?
请注意 ObjectPool 是模板化的,因此任何类型的 class 都可以是它的类型,而不仅仅是下例中的 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);
}
如果使用 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);
利用移动语义和完美转发来降低分配成本:
template <typename... Args>
void add_new_way(Args&&... args)
{
mObjects[nextFreeIndex] = T{std::forward<Args>(args)...};
}
由于被赋值的对象是临时的,如果被赋值对象的移动赋值运算符存在,将被调用。这将使对象将任何昂贵的复制资源的所有权从临时资源转移到池中的对象。
如需进一步阅读,请查看此问题:What are move semantics?