2016-05-30 9 views
2

私は異なるタイプがすべてoperator++を実装するバリアント変数を持っています。バリアント変数に直接インクリメントを適用したいと思います。それを行う簡単な方法はありますか?それとも各タイプのスイッチでそれを適用する必要がありますか? STLのイテレータとブースト::バリアントの値を増やす

シンプル

typedef boost::variant< 
    std::vector<double>::iterator, 
    std::vector<double>::reverse_iterator, 
    std::set<double>::iterator, 
    std::set<double>::reverse_iterator 
> AnyIterator; 

void incr(AnyIterator& ai) 
{ 
    ++adi; // this doesn't compile: no match for operator++ blah blah blah 

    // Have I really to write this kind of ugly thing ? 
    if(ai.type() == typeid(std::vector<double>::iterator)) 
    ++boost::get<std::vector<double>::iterator>(ai); 
    else if(ai.type() == typeid(std::vector<double>::reverse_iterator)) 
    ++boost::get<std::vector<double>::reverse_iterator>(ai); 
    else if(ai.type() == typeid(std::set<double>::iterator)) 
    ++boost::get<std::set<double>::iterator>(ai); 
    else if(ai.type() == typeid(std::set<double>::reverse_iterator)) 
    ++boost::get<std::set<double>::reverse_iterator>(ai); 
} 

注:私はGCC 4.8.1を使用し、1.57を後押し。私はC++ 11からの解決を望んでいません。古いgccバージョンとの互換性のために使用できません。

+0

私はあなたがこの醜いコードを書くことから離れて得ることができるとは思わないが、あなたは、多くの場合、それを必要とする場合は、 'を実装することができあなたの 'AnyIterator'型のための++演算子です。 – Holt

答えて

4

あなたは、一般的なファンクタを定義し、そのファンクタでboost::apply_visitorを使用することができます。

namespace detail { 
struct incrementer { 
    template< typename T > 
    void operator()(T& x) const { ++x; } 
    typedef void result_type; 
}; 
} 

void incr(AnyIterator& ai) 
{ 
    boost::apply_visitor(detail::incrementer(),ai); 
} 
+0

私はその考えを見る。それはシンプルに見えます。ソリューションをコンパイルできますか?私はメモの中にいくつかの命題(コメントのためには長すぎる)を付けて、テンプレート控除に関するコンパイルエラーを持っています。さらに、なぜ構造体を 'detail'という名前空間に置くのでしょうか?それは単なる良いことではありませんか?その理由は? – Caduchon

+0

@カドション[私はエラーがない](http://melpon.org/wandbox/permlink/c9rNAtcSLpS2GrcB)。名前空間 'detail'は実際には不要です。 – cpplearner

+0

F **キング神!私は 'typedef void return_type;'を見逃しました。エラーは本当に理解することは不可能です!ありがとう、それは今働いている。 – Caduchon