C++03 標準ライブラリは、アロケータとなるクラスに型を渡すときに、単純なテンプレート型引数を使用します。これは、テンプレートが C++ でどのように機能するかによって可能になります。ただし、これはそれほど単純ではなく、特に非標準型の場合、型定義が正確にどのように見えるべきかがわからない場合があります。
アダプタ クラスをインストレッドで使用することをお勧めします。私が何を意味するかを示すために、例を作成しました。
#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 */
実装は明らかであるべきです。使用例をいくつか示します。
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();
}
これは通常の方法と比較して改善されていますか?