Boost :: Container :: Vector with Enum Template Argument - Not Legal Base Class

时间:2010-04-20 20:43:06

标签: c++ stl boost vector enums

我正在使用Visual Studio 2008和Boost v1.42.0库。如果我使用枚举作为模板参数,则在使用push_back()添加值时会出现编译错误。编译器错误为:'T': is not a legal base class,错误的位置为move.hpp第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;
}

如果我使用std::vector代替它可行。如果我首先调整Boost版本然后使用[]运算符设置值,它也可以。

有没有办法让这项工作使用push_back()

<小时/> 模板回溯错误:

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 个答案:

答案 0 :(得分:1)

我认为你发现了一个真正的错误。我已发布到Boost ML来跟踪问题并尝试获取更多信息。

目前我看到的单一解决方法是将rv类专门化,如下所示,但我不确定这将适用于所有情况。

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

}}

如果这不起作用,您可以尝试使用int而不是枚举。

 enum {
  Unknown = 0,
  First = 1,
  Second = 2,
  Third = 3
 };
 typedef int Types; 

当然,这有损失枚举安全性的缺点。

答案 1 :(得分:0)

听起来Boost有一些错误的逻辑来决定是否从T派生。

天真地,人们可能会认为除了本机类型或指针之外的任何类型都可以用作基础。然而enum既不是基础也不是原始的。也许他们没有考虑到这一点。

看起来Boost错误地确定enum与其rvalue-reference仿真兼容。

解决此问题的最佳方法是避免在Boost Interprocess结构中使用枚举。

像黑客一样

namespace boost {
namespace interprocess { // get inside boost
template<>
class is_movable<Test::Types> // add custom specialization of is_movable
   : public ::boost::mpl::bool_<false>
{};
}}

可能会补丁。未经测试。

#include之后立即添加,以便在首次使用之前显示。