Шаблонная мета-магия C ++, механизм вывода квалификационных оценок шаблона сайта вызова - PullRequest
2 голосов
/ 16 марта 2011

Я извиняюсь за многословность этого примера, я придумал его из проекта.Комментарии, пункт 1 и пункт два, важны в следующем коде.

#include <boost/intrusive/set.hpp>

struct x : public boost::intrusive::set_base_hook<>
{
    int y;
};

struct finder
{
    bool operator()(const int & i, const x & _x) const
    { return i < _x.y;}
    bool operator()(const x & _x, const int & i) const
        { return _x.y < i;}
};

class trampoline
{
public:
    void bounce() const /* item 1 */
    {
        /*item 2*/
        boost::intrusive::set<x>::iterator it = _set.find(1,finder()); 
    }

    boost::intrusive::set<x> _set;
};

int main()
{
    trampoline t;
    t.bounce();
}

Я не могу взять неконстантный итератор в мой контейнер-член (пункт 2), где функция в области видимости является константной, еслиЯ переключаю итератор на const_iterator, все работает нормально, или если я делаю включающую функцию неконстантной, она также работает.Имеет смысл, теперь, после часа обратного инжиниринга, проблема из следующего сообщения об ошибке:

test.cc: В функции-члене 'void trampoline :: bounce () const': test.cc: 21: ошибка: преобразование из 'boost :: intrusive :: tree_iterator, (boost :: intrusive :: link_mode_type) 1u, boost :: intrusive :: default_tag, 3>, std :: less , длинный беззнаковый int, true>>, true> 'в нескалярный тип' boost:: навязчивый :: tree_iterator, (boost :: intrusive :: link_mode_type) 1u, boost :: intrusive :: default_tag, 3>, std :: less , длинный беззнаковый int, true>>, false> 'запрошено

Что в итоге привело меня к следующему определению шаблона (/include/boost/intrusive/detail/tree_node.hpp +72):

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//                   Implementation of the tree iterator                   //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

// tree_iterator provides some basic functions for a 
// node oriented bidirectional iterator:
template<class Container, bool IsConst>

Достаточно, так что я решил проблему вскоре после ....

Как, черт возьми, этот шаблон передается IsConst с места вызова включающей функции?Мой мозг готов взорваться (насколько я знаю, это что-то простое, но я озадачен).Было бы полезно подробное объяснение с пошаговой реализацией для объяснения механики.

У меня есть похожий вопрос здесь , похожий в отношении вывода типа / псевдонима шаблонного механизмаC ++.ссылки приветствуются, но их необходимо объединить в знания: D.Если у вас хватит терпения ответить на этот вопрос, вы можете попытаться сформировать беседу по другому вопросу.

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Не будет ли функция-член find () boost::intrusive::set просто иметь постоянную и неконстантную перегрузку?Я имею в виду, вот как бы я это сделал:

template <typename T /*...*/ >
class set {
  //... 
  public:
    template <bool isConst>
    class iterator {
      //....
    };
    iterator<true> find(/*..*/) const; //notice the const
    iterator<false> find(/*..*/);      //notice no const
};

Это на самом деле не магия метапрограммирования, а просто старая доброта.

1 голос
/ 16 марта 2011

как это?

Foo<false> bar();
Foo<true> bar() const;
...