没有可变参数模板的通用分配器类?
我正在尝试编写一个通用分配器类,该类在 free() 时不会真正释放对象的内存,而是将其保存在队列中,并在请求新对象时返回先前分配的对象。现在,我无法理解的是如何在使用分配器时将参数传递给对象的构造函数(至少不诉诸可变参数模板)。我想出的 alloc() 函数如下所示:
template <typename... T>
inline T *alloc(const &T... args) {
T *p;
if (_free.empty()) {
p = new T(args...);
} else {
p = _free.front();
_free.pop();
// to call the ctor of T, we need to first call its DTor
p->~T();
p = new( p ) T(args...);
}
return p;
}
尽管如此,我需要代码与当今的 C++(以及不支持可变参数模板的旧版本 GCC)兼容。还有其他方法可以将任意数量的参数传递给对象构造函数吗?
I am trying to write a generic allocator class that does not really release an object's memory when it is free()'d but holds it in a queue and returns a previously allocated object if a new one is requested. Now, what I can't wrap my head around is how to pass arguments to the object's constructor when using my allocator (at least without resorting to variadic templates, that is). The alloc() function i came up with looks like this:
template <typename... T>
inline T *alloc(const &T... args) {
T *p;
if (_free.empty()) {
p = new T(args...);
} else {
p = _free.front();
_free.pop();
// to call the ctor of T, we need to first call its DTor
p->~T();
p = new( p ) T(args...);
}
return p;
}
Still, I need the code to be compatible with today's C++ (and older versions of GCC that do not support variadic templates). Is there any other way to go about passing an arbitrary amount of arguments to the objects constructor?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您需要针对 C++0x 之前的编译器时,您需要提供伪变量模板,即您需要为每个所需的数量提供模板函数:
您可以使用 预处理器元编程虽然可以处理重复,例如通过使用 Boost.Preprocessor 或使用简单的脚本生成函数。
以下是使用 Boost.PP 的简单示例:
这将为您生成最多 10 个参数的
alloc()
模板函数。When you need to target pre-C++0x compilers you need to provide pseudo-variadic templates, i.e. you need to provide a template function for every needed arity:
You can use preprocessor metaprogramming though to handle the repititions, e.g. by using Boost.Preprocessor or by simply generating the functions using a simple script.
Following is a simple example using Boost.PP:
This generates you
alloc()
template functions for up to 10 arguments.C++11 之前的问题解决方案是仅提供一个简单的
alloc
函数来构造其参数的副本。这就是 C++03 分配器和所有容器的工作方式,持续了 20 多年。将其应用到您的代码中,它会变成:然后您将其称为:
这种方法的缺点是它需要一个可用的复制构造函数,并且它可能是一个昂贵的操作。
再举一个例子:
The pre-C++11 solution to the problem is to provide only one simple
alloc
function which constructs a copy of its argument. This is the way C++03 allocators and all the containers worked, for more than 20 years. Applying it to your code it becomes:And then you call it as:
The downside of this approach is that it requires a copy-constructor to be available, and its potentially a costly operation.
One more example: