【发布时间】:2015-11-20 14:26:45
【问题描述】:
我正在尝试创建一个仅移动类型的 stl 容器,该容器在 VStudio 2012 中使用其自己的分配器。
问题是:似乎我必须为分配器提供构造函数,而分配器又需要访问包含类型的公共复制构造函数。
我要么得到:
错误 C2248:“std::unique_ptr<_ty>::unique_ptr”:无法访问在类“std::unique_ptr<_ty>”中声明的私有成员
或
错误 C2039: 'construct' : is not a member of '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;
}
【问题讨论】:
-
你用哪个clang版本编译这个? gcc.godbolt.org 似乎显示了不同的结果 - 用 clang 编译也失败了。
-
让
construct将T&&作为第二个参数,并从它移开。更一般地说,在 C++11 下,construct应该采用任意一组参数,并执行new(p) T(std::forward(args))的等价物(不确定 VC12 是否足够好地支持 C++11 以允许这样做)。这是支持emplace和类似内容所必需的。
标签: c++11 visual-studio-2012 stl allocator