Boost :: Container :: Vector с аргументом шаблона Enum - недопустимый базовый класс - PullRequest
2 голосов
/ 21 апреля 2010

Я использую Visual Studio 2008 с библиотекой Boost v1.42.0. Если я использую enum в качестве аргумента шаблона, я получаю ошибку компиляции при добавлении значения, используя 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 ]

1 голос
/ 22 апреля 2010

Я думаю, вы нашли действительно ошибку. Я отправил сообщение в 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; 

Конечно, это имеет недостаток для потери безопасности enum.

0 голосов
/ 21 апреля 2010

Похоже, что Boost имеет некоторую ошибочную логику, чтобы определить, следует ли выводить из T или нет.

Наивно, можно предположить, что любой тип, кроме нативного типа или указателя, может использоваться в качестве базы. Однако enum s не являются ни базовыми, ни примитивными. Возможно, они не смогли объяснить это.

Похоже, что Boost неправильно определяет, что enum s совместимы с его эмуляцией 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 с, чтобы оно появилось перед первым использованием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...