C++ 将boost::ptr_向量添加到deque,typeid不匹配

C++ 将boost::ptr_向量添加到deque,typeid不匹配,c++,boost,ptr-vector,C++,Boost,Ptr Vector,我试图使用push_back()将boost::ptr_向量添加到std::deque。当我这样做时,我会得到一个BOOST::ASSERT来表示typeid不匹配 在“boost\u ptr\u container\u clone\u分配器”中 从TotalView中,res和r: Function "boost::new_clone<diagnostic_database_loader::DiagnosticDBClass>": r:

我试图使用push_back()将boost::ptr_向量添加到std::deque。当我这样做时,我会得到一个BOOST::ASSERT来表示typeid不匹配

在“boost\u ptr\u container\u clone\u分配器”中

从TotalView中,
res
r

Function "boost::new_clone<diagnostic_database_loader::DiagnosticDBClass>":
r:                                    (diagnostic_database_loader::DiagnosticDBClass  const &)
Local variables:
res:                                  0x082534f8 -> (diagnostic_database_loader::DiagnosticDBClass)
我试着用一个简单的测试程序来重现这一点,但我没有同样的问题

#include "iostream"
#include <boost/ptr_container/ptr_vector.hpp>
#include <deque>

class Item
{
public:
  int my_val;
  Item() : my_val(1) { }

  int getMyVal() { return my_val; }
};
class SmallItem : public Item
{
public:
  SmallItem() : Item() { my_val = 2; }
};

class TinyItem : public SmallItem
{
public:
  TinyItem() : SmallItem() { my_val = 3; }
};

class MyClass
{
private:
  boost::ptr_vector<SmallItem> items_;  

public:
  MyClass() 
  { 
    for (int i = 0; i < 10; ++i)
    {
      SmallItem *it = new TinyItem();
      items_.push_back(it);
     }
  }

 std::auto_ptr<boost::ptr_vector<SmallItem> > getData() { return items_.release(); }
 };

std::deque<boost::ptr_vector<SmallItem> > Buffer;

int totalItems(boost::ptr_vector<SmallItem> &items)
{
  int total = 0;
  boost::ptr_vector<SmallItem>::iterator it;
  for (it = items.begin(); it != items.end(); ++it)
    total += (*it).getMyVal();
  return total;
}

int main(int argc, char **argv)
{
  MyClass cls;

  boost::ptr_vector<SmallItem> items(cls.getData());

  std::cout << "SmallItem typeid   " << typeid(items[0]).name() << std::endl;

  fprintf(stdout, "I found %d total!\n", totalItems(items));

  Buffer.push_back(items);

  fprintf(stdout, "I pushed back into the deque!\n");

   boost::ptr_vector<SmallItem> items2 = Buffer.front();
   Buffer.pop_front();
   fprintf(stdout, "I still found %d total in the new vector!\n", totalItems(items2));

  items2.release();
  fprintf(stdout, "I found %d total after I released!\n", totalItems(items2));

  return 0;
}
#包括“iostream”
#包括
#包括
类项目
{
公众:
在我的房间里;
Item():my_val(1){}
int getMyVal(){返回我的值;}
};
类SmallItem:公共项
{
公众:
SmallItem():Item(){my_val=2;}
};
TinyItem类:公共小型项目
{
公众:
TinyItem():SmallItem(){my_val=3;}
};
类MyClass
{
私人:
boost::ptr_向量项;
公众:
MyClass()
{ 
对于(int i=0;i<10;++i)
{
SmallItem*it=new TinyItem();
项目推后(it);
}
}
std::auto_ptr getData(){return items_u.release();}
};
std::deque缓冲区;
整数总计项目(boost::ptr_向量和项目)
{
int-total=0;
boost::ptr_vector::迭代器it;
for(it=items.begin();it!=items.end();+it)
总计+=(*it).getMyVal();
返回总数;
}
int main(int argc,字符**argv)
{
MyClass cls;
boost::ptr_向量项(cls.getData());

std::cout您应该专门化
新建克隆
删除克隆
功能,如中所述

或者,您可以指定自己的作为
ptr\u vector
的第二个参数:

class Item
{
public:
  int my_val;
  Item() : my_val(1) { }

  Item* clone() const
  {
    Item* item = do_clone();
    BOOST_ASSERT(typeid(*this) == typeid(*item) &&
                 "do_clone() sliced object!");
    return item;
  }

  int getMyVal() { return my_val; }

private:
  // new virtual member function, overload in all derived classes.
  virtual Item* do_clone() const
  {
    return new Item(*this);
  }
};

class SmallItem : public Item
{
public:
  SmallItem() : Item() { my_val = 2; }

private:
  virtual Item* do_clone() const
  {
    return new SmallItem(*this);
  }
};

struct ItemCloner
{
  static Item* allocate_clone(const Item& item)
  {
    return item.clone();
  }

  static void deallocate_clone(const Item* item)
  {
    delete item;
  }
};

int main()
{
   boost::ptr_vector<Item, ItemCloner> items;
   // and so on...
}
类项目
{
公众:
在我的房间里;
Item():my_val(1){}
项*克隆()常量
{
Item*Item=do_clone();
BOOST_断言(typeid(*this)=typeid(*item)&&
“do_clone()切片对象!”);
退货项目;
}
int getMyVal(){返回我的值;}
私人:
//新的虚拟成员函数,在所有派生类中重载。
虚拟项*do_clone()常量
{
返回新项目(*此项);
}
};
类SmallItem:公共项
{
公众:
SmallItem():Item(){my_val=2;}
私人:
虚拟项*do_clone()常量
{
返回新的小项目(*此项);
}
};
结构项克隆器
{
静态项目*分配\克隆(常量项目和项目)
{
返回item.clone();
}
静态无效解除分配\u克隆(常量项*项)
{
删除项目;
}
};
int main()
{
boost::ptr_向量项;
//等等。。。
}

谢谢,我试用了“ItemCloner”方法,它在我的程序中起作用。首选哪种实现?似乎在每个向量中指定克隆器有点麻烦。有了这些克隆器,这是否意味着我们要为每个数组版本制作一个副本?@kevbo:每次复制
ptr\u向量时,它的内部数据也会被复制。如果你不想这样做的话您可能应该改用
vector
#include "iostream"
#include <boost/ptr_container/ptr_vector.hpp>
#include <deque>

class Item
{
public:
  int my_val;
  Item() : my_val(1) { }

  int getMyVal() { return my_val; }
};
class SmallItem : public Item
{
public:
  SmallItem() : Item() { my_val = 2; }
};

class TinyItem : public SmallItem
{
public:
  TinyItem() : SmallItem() { my_val = 3; }
};

class MyClass
{
private:
  boost::ptr_vector<SmallItem> items_;  

public:
  MyClass() 
  { 
    for (int i = 0; i < 10; ++i)
    {
      SmallItem *it = new TinyItem();
      items_.push_back(it);
     }
  }

 std::auto_ptr<boost::ptr_vector<SmallItem> > getData() { return items_.release(); }
 };

std::deque<boost::ptr_vector<SmallItem> > Buffer;

int totalItems(boost::ptr_vector<SmallItem> &items)
{
  int total = 0;
  boost::ptr_vector<SmallItem>::iterator it;
  for (it = items.begin(); it != items.end(); ++it)
    total += (*it).getMyVal();
  return total;
}

int main(int argc, char **argv)
{
  MyClass cls;

  boost::ptr_vector<SmallItem> items(cls.getData());

  std::cout << "SmallItem typeid   " << typeid(items[0]).name() << std::endl;

  fprintf(stdout, "I found %d total!\n", totalItems(items));

  Buffer.push_back(items);

  fprintf(stdout, "I pushed back into the deque!\n");

   boost::ptr_vector<SmallItem> items2 = Buffer.front();
   Buffer.pop_front();
   fprintf(stdout, "I still found %d total in the new vector!\n", totalItems(items2));

  items2.release();
  fprintf(stdout, "I found %d total after I released!\n", totalItems(items2));

  return 0;
}
class Item
{
public:
  int my_val;
  Item() : my_val(1) { }

  Item* clone() const
  {
    Item* item = do_clone();
    BOOST_ASSERT(typeid(*this) == typeid(*item) &&
                 "do_clone() sliced object!");
    return item;
  }

  int getMyVal() { return my_val; }

private:
  // new virtual member function, overload in all derived classes.
  virtual Item* do_clone() const
  {
    return new Item(*this);
  }
};

class SmallItem : public Item
{
public:
  SmallItem() : Item() { my_val = 2; }

private:
  virtual Item* do_clone() const
  {
    return new SmallItem(*this);
  }
};

struct ItemCloner
{
  static Item* allocate_clone(const Item& item)
  {
    return item.clone();
  }

  static void deallocate_clone(const Item* item)
  {
    delete item;
  }
};

int main()
{
   boost::ptr_vector<Item, ItemCloner> items;
   // and so on...
}