Boost::Container::Vector with Enum Template Argument - Not Legal Base Class
I'm using Visual Studi开发者_C百科o 2008 with the Boost v1.42.0 library. If I use an enum as the template argument, I get a compile error when adding a value using push_back()
. The compiler error is: 'T': is not a legal base class
and the location of the error is move.hpp
line 79.
#include <boost/interprocess/containers/vector.hpp>
class Test {
public:
enum Types {
Unknown = 0,
First = 1,
Second = 2,
Third = 3
};
typedef boost::container::vector<Types> TypesVector;
};
int main() {
Test::TypesVector o;
o.push_back(Test::First);
return 0;
}
If I use a std::vector
instead it works. And if I resize the Boost version first and then set the values using the []
operator it also works.
Is there some way to make this work using push_back()
?
Template backtrace of the error:
error C2516: 'T' : is not a legal base class 1> main.cpp(21) : see declaration of 'T' 1> main.cpp(21) : see reference to class template instantiation 'boost::interprocess::rv' being compiled 1> with 1> [ 1> T=Test::Types 1> ]
I think you have find really a bug. I have posted to the Boost ML to track the issue and try to have more info.
For the moment the single workaround I see is to specialize the rv class as follows, but I'm not sure this will work on all the cases.
namespace boost {
namespace interprocess {
template <>
class rv<Test::Types>
{
Test::Types v;
rv();
~rv();
rv(rv const&);
void operator=(rv const&);
operator Test::Types() const {return v;}
};
}}
If this do not works you can try using int instead of enum.
enum {
Unknown = 0,
First = 1,
Second = 2,
Third = 3
};
typedef int Types;
Of course this has the drawback to loss the enum safety.
It sounds like Boost has some erroneous logic to determine whether to derive from T
or not.
Naively, one might assume that any type besides a native type or pointer may be used as a base. However enum
s are neither bases nor primitive. Perhaps they failed to account for that.
It looks like Boost is incorrectly determining that enum
s are compatible with its rvalue-reference emulation.
The best way to solve this is to avoid use of enums in Boost Interprocess structures.
A hack like
namespace boost {
namespace interprocess { // get inside boost
template<>
class is_movable<Test::Types> // add custom specialization of is_movable
: public ::boost::mpl::bool_<false>
{};
}}
might patch things up. Untested.
Add this right after your #include
s so it appears before the first use.
精彩评论