簡體   English   中英

迭代器類型應該在這個C ++模板中應該是什么?

[英]What should the iterator type be in this C++ template?

在前一段時間處理一些圖形代碼時,我使用int作為底層坐標持有者編寫了Rect和Region類,並且工作正常。 Region實現為STL列表的簡單類擴展,只包含一個Rects列表。

現在我還需要使用雙精度作為底層坐標持有者的同類課程,並決定嘗試將其模板化。 所以我基本上以“智能方式”將“int”替換為“typename T”並修復了問題。

但是還有一個問題讓我難過。 我想通過在構成它的所有Rect上進行並集來計算Region的邊界框。 在沒有模板化的情況下工作正常,但是當它被模板化時,g ++會在列表迭代器上產生扼流圈。

這是相關的代碼:

// 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是明確的(例如int)時,“iterator i”行工作正常。 但是你在上面看到的,Ubuntu上的g ++會發出錯誤,我發現這些錯誤信息非常豐富:

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;

但似乎沒什么用。

有什么建議?

iterator是一個依賴類型(它取決於模板參數),需要以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;
    // ...
};

我認為gf有你的答案 ,但我想建議讓區域管理列表作為成員而不是基類:

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

我對此建議的動機是,有一天,您可能希望使用不同的容器來存儲您的KRect,並且將列表作為內部成員可以讓您這樣做而不會破壞所有客戶端代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM