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>]
+2


a source to share


2 answers


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.

+1


a source


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.

0


a source







All Articles