C++ 自定义分配器:const_pointer 'has not been declared'
C++ custom allocator: const_pointer 'has not been declared'
我在为自定义分配器编写自定义 'allocate' 方法时遇到问题。根据 cppreference 此方法的签名如下:
pointer allocate( size_type n, std::allocator<void>::const_pointer hint = 0 );
然而,当我为我的分配器定义这个方法时,我从编译器收到消息“'const_pointer' 尚未声明”。下面是显示问题的精简代码。
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(unsigned int n,
linear_allocator<void>::const_pointer hint = 0)
{
return 0;
}
};
int main()
{
linear_allocator<double> test_allocator;
}
一定是我遗漏了一些简单的东西,但是什么?
问题是由 linear_allocator<void>
class 模板在自身内部的显式实例化引起的。您可能应该将其设为单独的非模板基础 class。
如果你正在处理 C++17,那么你可以简单地编写这个函数来匹配新规范:
pointer allocate(std::size_t n)
您可以在分配器中为 void_pointer
和 const_void_pointer
显式提供别名。 Allocator is that the parameter matches allocator_traits<Alloc>::const_void_pointer
中的(可选)要求是
Alloc::const_void_pointer
if present, otherwise std::pointer_traits<pointer>::rebind<const void>
清理完毕,得到
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef unsigned int size_type;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(size_type n, const_void_pointer hint = nullptr)
{
return 0;
}
};
我研究了 stl::allocator 实施(应该从头开始)。正如 VTT 用户指出的那样,问题是由 linear_allocator<void>
内部的显式实例化引起的。我自己也一样,但对方法定义看起来好像应该有效感到困惑 'as it is'。
显然有很多方法可以解决这个问题——最简单的就是使用 const void*
作为 hint
的类型。我很想知道为什么它适用于标准 stl::allocator
而不是我的情况。
所以,在研究了这里的实现之后,就是解决方案:
- 声明模板化 class 'linear_allocator'.
- 使用明确的模板名称
<void>
定义 class linear_allocator
-- 我们只需要部分定义 class -- 只需输入我们将要使用的类型。
- 为通用模板 class 名称定义
linear_allocator
。
工作代码如下:
template <typename T>
class linear_allocator;
template <>
class linear_allocator<void>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
};
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(unsigned int n,
linear_allocator<void>::const_pointer hint = 0)
{
return 0;
}
};
int main()
{
linear_allocator<double> test_allocator;
}
我在为自定义分配器编写自定义 'allocate' 方法时遇到问题。根据 cppreference 此方法的签名如下:
pointer allocate( size_type n, std::allocator<void>::const_pointer hint = 0 );
然而,当我为我的分配器定义这个方法时,我从编译器收到消息“'const_pointer' 尚未声明”。下面是显示问题的精简代码。
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(unsigned int n,
linear_allocator<void>::const_pointer hint = 0)
{
return 0;
}
};
int main()
{
linear_allocator<double> test_allocator;
}
一定是我遗漏了一些简单的东西,但是什么?
问题是由 linear_allocator<void>
class 模板在自身内部的显式实例化引起的。您可能应该将其设为单独的非模板基础 class。
如果你正在处理 C++17,那么你可以简单地编写这个函数来匹配新规范:
pointer allocate(std::size_t n)
您可以在分配器中为 void_pointer
和 const_void_pointer
显式提供别名。 Allocator is that the parameter matches allocator_traits<Alloc>::const_void_pointer
中的(可选)要求是
Alloc::const_void_pointer
if present, otherwisestd::pointer_traits<pointer>::rebind<const void>
清理完毕,得到
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef unsigned int size_type;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(size_type n, const_void_pointer hint = nullptr)
{
return 0;
}
};
我研究了 stl::allocator 实施(应该从头开始)。正如 VTT 用户指出的那样,问题是由 linear_allocator<void>
内部的显式实例化引起的。我自己也一样,但对方法定义看起来好像应该有效感到困惑 'as it is'。
显然有很多方法可以解决这个问题——最简单的就是使用 const void*
作为 hint
的类型。我很想知道为什么它适用于标准 stl::allocator
而不是我的情况。
所以,在研究了这里的实现之后,就是解决方案:
- 声明模板化 class 'linear_allocator'.
- 使用明确的模板名称
<void>
定义 classlinear_allocator
-- 我们只需要部分定义 class -- 只需输入我们将要使用的类型。 - 为通用模板 class 名称定义
linear_allocator
。
工作代码如下:
template <typename T>
class linear_allocator;
template <>
class linear_allocator<void>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
};
template <class T>
class linear_allocator
{
public:
typedef T* pointer;
typedef const T* const_pointer;
linear_allocator() {}
~linear_allocator() {}
pointer allocate(unsigned int n,
linear_allocator<void>::const_pointer hint = 0)
{
return 0;
}
};
int main()
{
linear_allocator<double> test_allocator;
}