11

I have written a simple C++11 style stateful allocator type. Given

template<typename T> class my_allocator {
   // the usual stuff
};

template<typename T> using my_vector = std::vector<T, my_allocator<T>>;

my_vector<int> x;

std::vector<int> y = x; // error

What is the best way to allow conversions from a my_vector to a std::vector using the default allocator? GCC 4.7 (recent svn) says

error: conversion from 'my_vector<int> {aka std::vector<int, my_allocator<int>>}' to non-scalar type 'std::vector<int>' requested

Obviously this could be done with, say, a simple conversion function such as

template<typename T> std::vector<T> to_std_vec(const my_vector<T>& v)  {
   return std::vector<T>(&v[0], &v[v.size()]);
   }

but this seems pretty inelegant. Is there a better solution in C++11?

Move semantics are right out in this situation, of course, but I'd like copy construction and assignment to work without extra noise/typing.

4

3 回答 3

14

您不可能希望绕过明显的副本:std::vector<int> y(x.begin(), x.end();. in 中的元素y将由 分配std::allocator,而 inx中的元素由您自己的分配器分配并销毁。这两个分配器可能有完全不相关的内存指针概念!一个分配器使用的内存存储没有任何理由与另一个分配器相关。

除了制作语义元素副本之外,您还能做什么?

如果你不再想要旧容器,你应该做一个move,但是:

std::vector<int> y(std::make_move_iterator(x.begin()),
                   std::make_move_iterator(x.end()));

(如果元素有自己的分配器,这将有所帮助。int当然,不是为了。)

更新:为了强调这一点,请注意 a 的内部数据缓冲区vector<T, Alloc>不是type ,而是type。没有理由认为这些是两个不同分配器的相关类型。T*Alloc::pointer

于 2011-11-19T00:43:14.957 回答
2

您的问题有3种解决方案:

I.如果您的向量 'y' 尚不存在,您可以使用:

std::vector<int> y(x.begin(), x.end());

二、如果您的向量 'y' 已经存在,您可以使用:(例如,对于一个类的成员)

this->y.assign(x.begin(), x.end());

这两种填充向量的方法不是查看容器类型。(因此分配器类型)

三、另一种解决方案是创建一个父类,它可以用作标准分配器和您自己的分配器之间的分配器适配器。在这种情况下,您的 2 个分配器属于同一类型,并且可以与 operator=() 等向量方法一起使用。

于 2013-01-15T14:56:07.090 回答
2

嗯,我认为您在这里唯一的选择是完整副本,例如:

std::vector<int> y( x.begin(), x.end());
于 2011-11-19T00:39:29.453 回答