mardi 3 février 2015

Getting Howard Hinnant's short_alloc (C++11 version) to compile in Visual C++ 2015

I'd like to be able to use a custom allocator with std::vector so that small data buffers (say, less than 1024 bytes) are stored on the stack, and only longer vectors are stored on the heap. As one who has a background in Fortran, it causes me physical pain each time I have to do a heap memory allocation to store half-a-dozen elements for the duration of a five-line subroutine!


Howard Hinnant has published his short_alloc allocator which does exactly what I'm looking for, and if I compile it with gcc it works a treat. However, in Visual C++ I can't get it to compile. In Visual C++ 2013 part of the problem was that that too many C++11 keywords were unsupported, but I still came up against a problem even when I had #DEFINE'd all of these away. Today I tried compiling in Visual C++ 2015 CTP 5, and the keywords are now all supported but the compilation ultimately fails for the same reason.


The problem is this: for a reason I can't claim to understand fully, Hinnant's code defaults the copy constructor but deletes the copy assignment operator:



short_alloc(const short_alloc&) = default;
short_alloc& operator=(const short_alloc&) = delete;


When attempting to compile, this triggers the following error in Visual C++:



xmemory0(892): error C2280: 'short_alloc<int,1024> &short_alloc<1024>::operator =(const short_alloc<1024> &)': attempting to reference a deleted function


What confuses me even more is that if I modify Hinnant's code to say



short_alloc(const short_alloc&) = default;
short_alloc& operator=(const short_alloc&) = default;


...then I still obtain exactly the same error message.


For reference, here is my test code:



#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;
}


The compilation error goes away if I comment-out the line saying



theVector = std::move(anothertestvec);


so obviously the underlying problem is that Visual C++ approaches the copy in a different way from gcc. Even so, I'm at a loss for how to proceed from here. Is there a way to get this to work in Visual C++?


Aucun commentaire:

Enregistrer un commentaire