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

しかし、うまくいきませんでした。

編集:助けてくれてありがとう!しかし、私の設計では、リストから 1 つの要素を取得し、それをコードの他の部分に渡す必要があります (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<...>参照または const 参照が生成されます。

ただし、コードの残りの部分はバリアントに対応する必要があることを意味します。特に を使用し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 アルゴリズムの述語が自動的に生成されることに注意してください。

さて、戻り値の問題について:

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:

簡単ですが、実際には少しコーチングが必要です:)

まず、次の 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));

    }

  }
}

for each はここではあまり良くありませんif。ただし、何らかの形で因数分解できれば機能ifoperateます。

また、イテレータではなく参照を渡すことにも注意してください。

于 2010-06-09T06:24:11.513 に答える