2

I have a variant variable where the different types all implement operator++. I would like to apply incrementation directly on the variant variable. Is there an easy way to do that ? Or have I to apply it in a switch on each type ?

Simple example with stl iterators :

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

Note : I use gcc 4.8.1 and Boost 1.57. I don't want solution from C++11, I can't use it due to compatibility with old gcc versions.

Caduchon
  • 4,574
  • 4
  • 26
  • 67
  • I don't think you can get away from writing this ugly code, but if you need it often you could implement the `++` operator for your `AnyIterator` type. – Holt May 30 '16 at 13:46

1 Answers1

4

You can define a generic functor and then use boost::apply_visitor with that functor:

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);
}
cpplearner
  • 13,776
  • 2
  • 47
  • 72
  • I see the idea. It looks simple. Can you try to compile your solution ? I have a compilation error about template deduction, with several propositions in notes (too long for a comment). Moreover, why put the structure in the namespace `detail` ? Is it just un good practice ? For which reason ? – Caduchon May 30 '16 at 15:19
  • @Caduchon [I see no error](http://melpon.org/wandbox/permlink/c9rNAtcSLpS2GrcB). namespace `detail` is indeed unnecessary. – cpplearner May 30 '16 at 15:31
  • F**king God ! I missed the `typedef void return_type;`. The error is really impossible to understand ! Thanks, it's working now. – Caduchon May 30 '16 at 19:06
  • 1
    It seems the better way is inheritance from `boost::static_visitor<>`. But the idea is there. – Caduchon May 31 '16 at 11:24