2016-05-30 3 views
2

У меня есть переменная варианта, где различные типы реализуют все operator++. Я хотел бы применить инкремент непосредственно к переменной варианта. Есть ли простой способ сделать это? Или мне нужно применить его в коммутаторе на каждом типе?Инкремент boost :: variant value

Простой пример с СТЛ итераторов:

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

@Caduchon [Я не вижу ошибки] (http://melpon.org/wandbox/permlink/c9rNAtcSLpS2GrcB). пространство имен 'detail' действительно не нужно. – cpplearner

+0

F ** царь Бог! Я пропустил 'typedef void return_type;'. Ошибки действительно невозможно понять! Спасибо, сейчас работает. – Caduchon

Смежные вопросы