2 votes

Boost::Container::Vector avec l'argument de modèle Enum - Classe de base non légale

J'utilise Visual Studio 2008 avec la bibliothèque Boost v1.42.0. Si j'utilise un enum comme argument du modèle, j'obtiens une erreur de compilation lorsque j'ajoute une valeur à l'aide de la commande push_back() . L'erreur du compilateur est la suivante : 'T': is not a legal base class et la localisation de l'erreur est move.hpp ligne 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;
}

Si j'utilise un std::vector au lieu de cela, cela fonctionne. Et si je redimensionne d'abord la version Boost et que je définis ensuite les valeurs à l'aide de la fonction [] L'opérateur fonctionne également.

Existe-t-il un moyen de faire fonctionner ce système en utilisant push_back() ?


Template backtrace de l'erreur :

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>        \]

1voto

Vicente Botet Escriba Points 2954

Je pense que vous avez trouvé un véritable bug. J'ai posté un message sur le Boost ML pour suivre le problème et essayer d'avoir plus d'informations.

Pour l'instant, la seule solution que je vois est de spécialiser la classe rv comme suit, mais je ne suis pas sûr que cela fonctionnera dans tous les cas.

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

}}

Si cela ne fonctionne pas, vous pouvez essayer d'utiliser int au lieu de enum.

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

Bien sûr, cela présente l'inconvénient de perdre la sécurité de l'enum.

0voto

Potatoswatter Points 70305

Il semble que Boost ait une logique erronée pour déterminer s'il faut dériver de T ou non.

Naïvement, on pourrait supposer que tout type autre qu'un type natif ou un pointeur peut être utilisé comme base. Cependant, il n'en est rien. enum ne sont ni des bases ni des primitives. Peut-être n'ont-ils pas tenu compte de cela.

Il semble que Boost détermine à tort que enum sont compatibles avec son émulation rvalue-référence.

La meilleure façon de résoudre ce problème est d'éviter d'utiliser les enums dans les structures Boost Interprocess.

Un hack comme

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

pourrait arranger les choses. Non testé.

Ajoutez ceci juste après votre #include afin qu'il apparaisse avant la première utilisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X