分配器类型参数的C ++设计模式 [英] C++ Design Pattern for allocator type arguments
问题描述
C ++ 03标准库在将类型传递给旨在作为分配器的类时使用简单的模板类型参数。这是可能的,因为模板在C ++中的工作原理。但是,它不是很简单,你可能不知道什么是类型定义应该是什么样的 - 特别是在非标准类型的情况下。
The C++03 standard library uses simple template type arguments when passing a type to a class which is meant to be an allocator. This is possible because of how templates work in C++. However, it isn't very straightforward and you might don't know what exactly the type definition should look like - especially in case of non standard types.
我以为可能是使用适配器类instread的好主意。我创建了一个例子来告诉你我的意思:
I thought it might be a good idea to use adaptor classes instread. I've created an example to show you what I mean:
#ifndef HPP_ALLOCATOR_ADAPTOR_INCLUDED
#define HPP_ALLOCATOR_ADAPTOR_INCLUDED
#include <memory>
template<typename T>
struct allocator_traits;
template<typename T, class allocator_type = std::allocator<T>>
class allocator_adaptor;
template<>
struct allocator_traits<void>
{
typedef std::allocator<void>::const_pointer const_pointer;
typedef std::allocator<void>::pointer pointer;
typedef std::allocator<void>::value_type value_type;
};
template<typename T>
struct allocator_traits
{
typedef typename std::allocator<T>::const_pointer const_pointer;
typedef typename std::allocator<T>::const_reference const_reference;
typedef typename std::allocator<T>::difference_type difference_type;
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::reference reference;
typedef typename std::allocator<T>::size_type size_type;
typedef typename std::allocator<T>::value_type value_type;
};
template<class allocator_type>
class allocator_adaptor<void, allocator_type>
: public allocator_traits<void>
{
public:
template<typename U> struct rebind { typedef allocator_adaptor<U, allocator_type> other; };
};
template<typename T, class allocator_type>
class allocator_adaptor
: public allocator_traits<T>
{
private:
allocator_type m_impl;
public:
template<typename U> struct rebind { typedef allocator_adaptor<U, allocator_type> other; };
allocator_adaptor() throw() /*noexcept*/;
allocator_adaptor(allocator_adaptor const&) throw() /*noexcept*/;
allocator_adaptor(allocator_type const&) throw() /*noexcept*/;
template<typename U> allocator_adaptor(allocator_adaptor<U, allocator_type> const&) throw() /*noexcept*/;
~allocator_adaptor() throw();
pointer address(reference x) const /*noexcept*/;
const_pointer address(const_reference x) const /*noexcept*/;
pointer allocate (size_type, allocator_traits<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n) /*noexcept*/;
size_type max_size () const throw() /*noexcept*/;
template<class U, typename... argument_types> void construct(U* p, argument_types&&... args);
template<class U> void destroy(U* p);
};
#endif /* HPP_ALLOCATOR_ADAPTOR_INCLUDED */
应该很明显
这里是一些使用示例。
The implemention should be obvious. Here's some usage example.
template<class allocator_type>
int max_size(allocator_type const& alloc)
{
// we don't know what kind of max_szie function will be called.
return alloc.max_size();
}
template<typename T>
int max_size(allocator_adaptor<T> const& alloc)
{
// we know what kind of max_size function will be called.
return alloc.max_size();
}
与通常的方式相比,这是一个改进吗?
is this an improvement compared to the usual way?
推荐答案
实际上,您的观点是引入基于可变参数的构造
你写的不是:
Actually your point here is to introduce a construct
member which is based on variadic arguments and allows you to write instead of:
typedef std::allocator<T> my_alloc;
my_alloc alloc;
my_alloc::pointer p = alloc.allocate(10);
alloc::construct(p, T(param1, param2, param3));
alloc::construct(p+1, T(param1, param2, param3));
//...
一些更容易的形式:
alloc::construct(p, param1, param2, param3);
alloc::construct(p+1, param1, param2, param3);
这似乎是一个很好的功能。另一方面,您移动所有初始化参数,这将禁止正确初始化p + 1对象。如果我想为多个对象重复相同参数的初始化怎么办?我认为你目前的做法会失败(不幸的是不是在编译时)。
This seems to be a nice feature. On the other hand, you move all the initialization parameters, which will prohibit the proper initialization of the p+1 object. What if I want to repeat the initialization for the same parameters for multiple objects. I think your current approach will fail (and unfortunately not at compile-time).
这篇关于分配器类型参数的C ++设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!