开发者

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 enums are neither bases nor primitive. Perhaps they failed to account for that.

It looks like Boost is incorrectly determining that enums 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 #includes so it appears before the first use.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜