Что итератор должен ввести быть в этом шаблоне C++?

В то время как работа над некоторой графикой кодирует некоторое время назад, я записал классы Rect и региона с помощью ints как базовый координатный держатель, и это хорошо работало. Регион был реализован как простое расширение класса списка STL и просто содержит список Rects.

Теперь мне также нужны те же виды использования классов, удваивается как базовый координатный держатель, и решенный, чтобы попробовать мои силы в templatizing это. Таким образом, я в основном заменил "интервал" "именем типа T" интеллектуальным способом и решил проблемы.

Но существует одна остающаяся проблема, которой озадачили меня. Я хочу вычислить ограничительную рамку региона путем выполнения объединения на всех Rect, которые включают его. Это хорошо работает если не templatized, но g ++ дроссели на итераторе списка, когда это - templatized.

Вот соответствующие нормы:

// Rect class that always remains normalized
template <typename T>
class KRect
{
public:

    // Ctors
    KRect(void)
        : _l(0), _t(0), _r(0), _b(0)
    {
    }
    void unionRect(const KRect& r)
    {
        ...
    }

private:
    T _l, _t, _r, _b;
};

// Region class - this is very brain-dead
template <typename T>
class KRegion : public std::list< KRect<T> >
{
public:
    ...

    // Accessors
    KRect<T> boundingBox(void)
    {
        KRect<T> r;
        iterator i;
        for (i = this->begin(); i != this->end(); i++)
        {
            r.unionRect(*i);
        }
        return r;
    }
    ...
};

Когда тот код не является частью шаблона, так, чтобы T был определенным (например, интервал), "итератор, i" строк хорошо работают. Но в то, что Вы видите выше, g ++ на Ubuntu, испускает ошибки, которые я не нахожу очень информативными:

include/KGraphicsUtils.h: In member function ‘KRect<T> KRegion<T>::boundingBox()’:
include/KGraphicsUtils.h:196: error: expected ‘;’ before ‘i’
include/KGraphicsUtils.h:197: error: ‘i’ was not declared in this scope
include/KGraphicsUtils.h: In member function ‘KRect<T> KRegion<T>::boundingBox() [with T = int]’:
--- redacted ---:111:   instantiated from here
include/KGraphicsUtils.h:196: error: dependent-name ‘std::foo::iterator’ is parsed as a non-type, but instantiation yields a type
include/KGraphicsUtils.h:196: note: say ‘typename std::foo::iterator’ if a type is meant

Мое предположение, это - проблема квалификации типа с некоторым шаблонным-y вращением, с которым я не знаком. Я попробовал все виды вещей как:

std::list< KRect<T> >::iterator i;
this->iterator i;

но ничто, кажется, не работает.

Какие-либо предложения?

5
задан outis 8 February 2010 в 01:41
поделиться

2 ответа

итератор является зависимым типом (зависит от аргумента шаблона) и требует с префиксом typename :

typename std::list< KRect<T> >::iterator i;

Лучшим стилем было бы предоставление typedef для всего класса:

template <typename T>
class KRegion : public std::list< KRect<T> >
{
    typedef std::list< KRect<T> > base;
    typedef typename base::iterator iterator;
    // ...
};
9
ответ дан 13 December 2019 в 05:34
поделиться

I think gf has your answer, but I'd like to suggest having the region manage a list as a member instead of a base class:

template <typename T>
class KRegion
{
protected:
     typedef std::list< KRect<T> > ListType;
     ListType list;
public:
    ...
    // Accessors
    void addRect(KRect<T> & rect) { list->push_back(rect); }
    ...
    KRect<T> boundingBox(void)
    {
        KRect<T> r;
        ListType::iterator i;
        for (i = list->begin(); i != list->end(); i++)
        {
            r.unionRect(*i);
        }
        return r;
    }
    ...
};

My motivation for this suggestion is that you may, one day, want to use a different container for storing your KRects, and having the list as an internal member would let you do so without breaking all of your client code.

3
ответ дан 13 December 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: