VStudio 2012 为仅移动类型的容器创建自定义分配器
VStudio 2012 Create custom allocator for container of move-only type
我正在尝试创建一个仅移动类型的 stl 容器,它在 VStudio 2012 中使用自己的分配器。
问题是:似乎我必须为分配器提供构造函数,而分配器又需要访问所包含类型的 public 复制构造函数。
我要么得到:
错误 C2248:'std::unique_ptr<_Ty>::unique_ptr':无法访问在 class 'std::unique_ptr<_Ty>'
中声明的私有成员
或
error C2039: 'construct' : 不是 'MyAllocator'
的成员
相同的代码在 clang 中有效,所以我怀疑问题是由于 Microsoft 造成的,但任何人都可以提出可能的解决方法吗?
这是我的最小复制代码
#include <memory>
#include <vector>
using namespace std;
template< typename T>
struct MyAllocator
{
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* const_pointer;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<class t_other>
struct rebind
{
typedef MyAllocator<t_other> other;
};
MyAllocator():m_id(0) {}
MyAllocator(int id):m_id(id){}
template <class T>
MyAllocator(const MyAllocator<T>& other)
:m_id(other.getId())
{
}
T* allocate(std::size_t n)
{
return reinterpret_cast<T*>(malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n)
{
free(p);
}
int getId() const{ return m_id;}
//Have to add these although should not be necessary
void construct(pointer mem, const_reference value)
{
std::_Construct(mem, value);
}
void destroy(pointer mem)
{
std::_Destroy(mem);
}
private:
int m_id;
};
template <class T1, class U>
bool operator==(const MyAllocator<T1>& lhs, const MyAllocator<U>& rhs)
{
return lhs.getId() == rhs.getId() ;
}
template <class T1, class U>
bool operator!=(const MyAllocator<T1>&, const MyAllocator<U>&)
{
return lhs.getId() != rhs.getId();
}
//define a move only type
typedef unique_ptr<uint32_t> MyIntPtr;
//define a container based on MyIntPtr and MyAllocator
typedef vector<MyIntPtr, MyAllocator<MyIntPtr> > MyVector;
int main(int argc, char* argv[])
{
MyAllocator<MyIntPtr> alloc1(1);
MyVector vec(alloc1);
uint32_t* rawPtr = new uint32_t;
*rawPtr = 18;
vec.emplace_back(rawPtr);
return 0;
}
您得到的错误是因为您试图从对相同类型的 std::unique_ptr
的常量引用构造一个 std::unique_ptr - 但没有这样的构造函数。
您可以修改您的 construct
方法以获取右值引用,然后一切都可以很好地编译:
void construct(pointer mem, value_type&& value)
{
std::_Construct(mem, std::move(value));
}
我正在尝试创建一个仅移动类型的 stl 容器,它在 VStudio 2012 中使用自己的分配器。
问题是:似乎我必须为分配器提供构造函数,而分配器又需要访问所包含类型的 public 复制构造函数。
我要么得到:
错误 C2248:'std::unique_ptr<_Ty>::unique_ptr':无法访问在 class 'std::unique_ptr<_Ty>'
中声明的私有成员或
error C2039: 'construct' : 不是 'MyAllocator'
的成员相同的代码在 clang 中有效,所以我怀疑问题是由于 Microsoft 造成的,但任何人都可以提出可能的解决方法吗?
这是我的最小复制代码
#include <memory>
#include <vector>
using namespace std;
template< typename T>
struct MyAllocator
{
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* const_pointer;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<class t_other>
struct rebind
{
typedef MyAllocator<t_other> other;
};
MyAllocator():m_id(0) {}
MyAllocator(int id):m_id(id){}
template <class T>
MyAllocator(const MyAllocator<T>& other)
:m_id(other.getId())
{
}
T* allocate(std::size_t n)
{
return reinterpret_cast<T*>(malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n)
{
free(p);
}
int getId() const{ return m_id;}
//Have to add these although should not be necessary
void construct(pointer mem, const_reference value)
{
std::_Construct(mem, value);
}
void destroy(pointer mem)
{
std::_Destroy(mem);
}
private:
int m_id;
};
template <class T1, class U>
bool operator==(const MyAllocator<T1>& lhs, const MyAllocator<U>& rhs)
{
return lhs.getId() == rhs.getId() ;
}
template <class T1, class U>
bool operator!=(const MyAllocator<T1>&, const MyAllocator<U>&)
{
return lhs.getId() != rhs.getId();
}
//define a move only type
typedef unique_ptr<uint32_t> MyIntPtr;
//define a container based on MyIntPtr and MyAllocator
typedef vector<MyIntPtr, MyAllocator<MyIntPtr> > MyVector;
int main(int argc, char* argv[])
{
MyAllocator<MyIntPtr> alloc1(1);
MyVector vec(alloc1);
uint32_t* rawPtr = new uint32_t;
*rawPtr = 18;
vec.emplace_back(rawPtr);
return 0;
}
您得到的错误是因为您试图从对相同类型的 std::unique_ptr
的常量引用构造一个 std::unique_ptr - 但没有这样的构造函数。
您可以修改您的 construct
方法以获取右值引用,然后一切都可以很好地编译:
void construct(pointer mem, value_type&& value)
{
std::_Construct(mem, std::move(value));
}