4

嘿那里,

我正在尝试使现有代码适应 boost::variant。这个想法是对异构向量使用 boost::variant。问题是其余代码使用迭代器来访问向量的元素。有没有办法将 boost::variant 与迭代器一起使用?

我试过了

 typedef boost::variant<Foo, Bar> Variant;
 std::vector<Variant> bag;
 std::vector<Variant>::iterator it;
 for(it= bag.begin(); it != bag.end(); ++it){

 cout<<(*it)<<endl;
 }

但它没有用。

编辑:谢谢你的帮助!但是在我的设计中,我需要从列表中获取一个元素并将其传递给代码的其他部分(这可能很糟糕,因为我使用的是 GSL)。使用迭代器的想法是我可以将迭代器传递给一个函数,该函数将对来自该特定元素的返回数据进行操作。我看不到如何使用 for_each 来做到这一点。我需要做类似的事情:

for(it=list.begin(); it!=list.end();++it) {
  for(it_2=list.begin(); it_2!=list.end();++it_2) {

     if(it->property() != it_2->property()) {

        result = operate(it,it_2);

       }
    }

}

谢谢!

4

1 回答 1

8

当然有。取消引用迭代器自然会产生boost::variant<...>引用或常量引用。

然而,这确实意味着其余代码应该是变体感知的。尤其是使用boost::static_visitor对变体执行操作。

编辑

简单的!

struct Printer: boost::static_visitor<>
{
  template <class T>
  void operator()(T const& t) const { std::cout << t << std::endl; }
};

std::for_each(bag.begin(), bag.end(), boost::apply_visitor(Printer());

请注意编写访问者如何自动生成 STL 算法的谓词,miam!

现在,对于返回值的问题:

class WithReturn: boost::static_visitor<>
{
public:
  WithReturn(int& result): mResult(result) {}

  void operator()(Foo const& f) const { mResult += f.suprise(); }
  void operator()(Bar const& b) const { mResult += b.another(); }

private:
  int& mResult;
};


int result;
std::for_each(bag.begin(), bag.end(), boost::apply_visitor(WithReturn(result)));

编辑2:

这很容易,但确实需要一些指导:)

首先,我们注意到有两种不同的操作:!=operate

 struct PropertyCompare: boost::static_visitor<bool>
 {
   template <class T, class U>
   bool operator()(T const& lhs, U const& rhs)
   {
     return lhs.property() == rhs.property();
   }
 };

 struct Operate: boost::static_visitor<result_type>
 {
   result_type operator()(Foo const& lhs, Foo const& rhs);
   result_type operator()(Foo const& lhs, Bar const& rhs);
   result_type operator()(Bar const& lhs, Bar const& rhs);
   result_type operator()(Bar const& lhs, Foo const& rhs);
 };

for(it=list.begin(); it!=list.end();++it) {
  for(it_2=list.begin(); it_2!=list.end();++it_2) {

    if( !boost::apply_visitor(PropertyCompare(), *it, *it_2) ) {

      result = boost::apply_visitor(Operate(), *it, *it_2));

    }

  }
}

因为这里的每个都不是那么好,因为这个if。如果你能以某种方式将其考虑在内,它会if起作用operate

另请注意,我传递的不是迭代器而是引用。

于 2010-06-09T06:24:11.513 回答