带有枚举模板参数的 Boost::Container::Vector - 不是合法的基类

发布于 2024-08-30 03:32:41 字数 1015 浏览 5 评论 0原文

我将 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()来完成这项工作?


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'm using Visual Studio 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>        ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

祁梦 2024-09-06 03:32:41

我想你确实发现了一个错误。我已发布到 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。

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

当然,这有一个缺点,即失去枚举安全性。

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.

差↓一点笑了 2024-09-06 03:32:41

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

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

Boost 似乎错误地确定了枚举与其右值引用模拟兼容。

解决此问题的最佳方法是避免在 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 之后,以便它在首次使用之前出现。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文