【发布时间】:2015-04-02 12:43:03
【问题描述】:
我希望能够将自定义分配器与 std::vector 一起使用,以便将小型数据缓冲区(例如,小于 1024 字节)存储在堆栈上,而只有更长的向量存储在堆上。作为一个有 Fortran 背景的人,每次我必须在五行子程序的持续时间内分配堆内存来存储六个元素时,都会让我感到痛苦!
Howard Hinnant 发布了他的 short_alloc 分配器,它完全符合我的要求,如果我用 gcc 编译它,它会很有效。但是,在 Visual C++ 中我无法编译它。在 Visual C++ 2013 中,部分问题是不支持太多的 C++11 关键字,但即使我将所有这些都去掉了#DEFINE,我仍然遇到了问题。今天尝试用Visual C++ 2015 CTP 5编译,现在关键字都支持了,但是同样的原因最终编译失败了。
问题是这样的:由于我无法完全理解的原因,Hinnant 的代码默认了复制构造函数,但删除了复制赋值运算符:
short_alloc(const short_alloc&) = default;
short_alloc& operator=(const short_alloc&) = delete;
尝试编译时,这会在 Visual C++ 中触发以下错误:
xmemory0(892): error C2280: 'short_alloc<int,1024> &short_alloc<1024>::operator =(const short_alloc<1024> &)': attempting to reference a deleted function
更让我困惑的是,如果我修改 Hinnant 的代码说
short_alloc(const short_alloc&) = default;
short_alloc& operator=(const short_alloc&) = default;
...那么我仍然得到完全相同的同样的错误信息。
供参考,这是我的测试代码:
#include <iostream>
#include <vector>
#include "short_alloc.h"
void populate_the_vector(std::vector<int, short_alloc<int, 1024> > &theVector)
{
arena<1024> B;
std::vector<int, short_alloc<int, 1024> > anothertestvec{(short_alloc<int, 1024>(B))};
anothertestvec.resize(10);
for (int i=0; i<10; ++i)
{
anothertestvec[i] = i;
}
theVector = std::move(anothertestvec); // Actually causes a copy, as the Arenas are different
}
int main()
{
arena<1024> A;
std::vector<int, short_alloc<int, 1024> > testvec{(short_alloc<int, 1024>(A))};
populate_the_vector(testvec);
printf("Testvec(10)=%d\r\n", testvec[5]);
return 0;
}
如果我注释掉这行,编译错误就会消失
theVector = std::move(anothertestvec);
很明显,潜在的问题是 Visual C++ 以与 gcc 不同的方式处理副本。即便如此,我还是不知道如何从这里开始。有没有办法让它在 Visual C++ 中工作?
【问题讨论】:
-
该赋值运算符可能对基类(编辑:或成员)不可用,因此生成默认实现也会导致删除。
-
@Mehrdad 没有基类,但它有一个引用成员。
-
另外,作为记录,我认为
pointer_in_buffer中的代码依赖于未定义的行为,实际上可能无法在不调用的情况下实现UB。 -
@Mehrdad 未指定,不是未定义。它也可以在没有未指定行为的情况下通过循环来实现,该循环测试指针是否与
buf、buf + 1、...、buf + N相等,但除非优化器足够聪明,否则这将导致性能的巨大损失。 -
回到原来的问题,
allocator_traits<short_alloc<...>>::propagate_on_container_move_assignment默认应该是false_type,所以vector的移动赋值不应该移动分配分配器。 MSVC 的vector或其allocator_traits出现问题。
标签: c++ visual-c++ c++11 memory allocation