Инстанцирование шаблонов C++
У меня есть следующий код:
namespace STDAllocators
{
template<class Derived>
struct IAllocator
{
typename Derived::pointer allocate(size_t count_objects);
void deallocate(typename Derived::pointer memory_pointer, size_t count_objects);
};
template<typename T>
class LinearAllocator : public IAllocator<LinearAllocator<T>>
{
public:
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
public:
LinearAllocator();
LinearAllocator(const LinearAllocator& other);
template<typename U>
LinearAllocator(const LinearAllocator<U>& other);
pointer allocateImpl(size_t count_objects);
void deallocateImpl(pointer memory_pointer, size_t count_objects);
};
}
И вот при инстанцировании шаблонов получаю не совсем понятную мне ошибку:
error: invalid use of incomplete type ‘struct STDAllocators::IAllocator<STDAllocators::LinearAllocator<int> >’
class LinearAllocator : public IAllocator<LinearAllocator<T>>
Кто-нибудь может подсказать в чем проблема?
Ответы (1 шт):
Автор решения: user7860670
→ Ссылка
Дело в том, что при использовании в списке базовых классов тип LinearAllocator<T> является неполным (incomplete ), т.е. как при наличии только предварительного объявления template<typename T> class LinearAllocator;. А для инстанцирования класса IAllocator должно быть доступна информации о наличии типа pointer в LinearAllocator.
Простейшим решением в такой ситуации может быть перенос (части) объявлений типов в базовый класс:
template<typename Derived, typename T> // Derived в такой форме оказывается не нужным
struct IAllocator
{
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
pointer allocate(size_t count_objects);
void deallocate(pointer memory_pointer, size_t count_objects);
};
template<typename T>
class LinearAllocator : public IAllocator<LinearAllocator<T>, T>
{
public: using t_Allocator = IAllocator<LinearAllocator<T>, T>;
public: using typename t_Allocator::value_type;
public: using typename t_Allocator::pointer;
public: using typename t_Allocator::const_pointer;
public:
LinearAllocator();
LinearAllocator(const LinearAllocator& other);
template<typename U>
LinearAllocator(const LinearAllocator<U>& other);
pointer allocateImpl(size_t count_objects);
void deallocateImpl(pointer memory_pointer, size_t count_objects);
};
или в дополнительный класс типажа:
template<typename Allocator>
struct AllocatorTraits;
template<typename Derived>
struct IAllocator
{
typename AllocatorTraits<Derived>::pointer allocate(size_t count_objects);
void deallocate(typename AllocatorTraits<Derived>::pointer memory_pointer, size_t count_objects);
};
template<typename T>
class LinearAllocator;
template<typename T>
struct AllocatorTraits<LinearAllocator<T>>
{
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
};
template<typename T>
class LinearAllocator : public IAllocator<LinearAllocator<T>>
{
public: using value_type = typename AllocatorTraits<LinearAllocator>::value_type;
public: using pointer = typename AllocatorTraits<LinearAllocator>::pointer;
public: using const_pointer = typename AllocatorTraits<LinearAllocator>::const_pointer;
public:
LinearAllocator();
LinearAllocator(const LinearAllocator& other);
template<typename U>
LinearAllocator(const LinearAllocator<U>& other);
pointer allocateImpl(size_t count_objects);
void deallocateImpl(pointer memory_pointer, size_t count_objects);
};