Boost :: Container :: Vector with template argument Enum is invalid base class
I am using Visual Studio 2008 with Boost v1.42.0 library. If I use enum as a template argument, I get a compile error when I add the value with push_back()
. Compiler error: 'T': is not a legal base class
and the error location is at 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 std::vector
it works. And if I first resize the Boost version and then set the values using an operator []
, it works as well.
Is there a way to make this work using push_back()
?
Original error template 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>]
a source to share
I think you actually found a bug. I posted to Boost ML to inquire about the issue and try to get more information.
At the moment, the only workaround I see is to specialize the rv class as follows, but I'm not sure if this will work in all 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 that doesn't work, 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 disadvantage of losing enumeration security.
a source to share
It looks like Boost has some flawed logic to determine whether to infer from T
or not.
It is naive to assume that any type can be used as a base, except for a native type or a pointer. However, enum
they are neither basic nor primitive. They may not have been able to explain it.
It looks like Boost misidentifies what is enum
compatible with its rvalue-reference emulation.
The best way to solve this is to avoid using enums in Interprocess Boost structures.
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>
{};
}}
can fix the situation. Unverified.
Add this right after yours #include
so it appears before first use.
a source to share