簡體   English   中英

operator-> 用於返回臨時值的迭代器

[英]operator-> for an iterator that returns a temporary

我有一個數據結構,它本質上是一個 hash 表。 出於緩存原因,鍵和值分開存儲。 我有一個遍歷容器並在取消引用時返回鍵和值對的迭代器。

但是,我在讓迭代器表現得像其他迭代器時遇到了一些麻煩。 特別是operator-> 這是我到目前為止所擁有的:

struct KeyValuePair
{
    KeyValuePair(const int& key, int& value) : key(key), value(value) {}

    const int& key;
    int& value;
};

struct Iterator
{
    KeyValuePair operator*() { return KeyValuePair(*keys, *values); }

    // TODO: Implement this
    //KeyValuePair* operator->() { return ... }

    int* keys = nullptr;
    int* values = nullptr;
};

這適用於 range-for 和顯式取消引用迭代器

auto it = container.begin();
KeyValuePair pair = *it;

但它不適用於“通過”迭代器,因為我沒有operator->

auto it = container.begin();
int& value = it->value;

而且我不知道如何為這個迭代器實現operator-> 我的第一個想法是在迭代器中插入一個KeyValuePair並返回一個指向它的指針,但是如果沒有惡作劇就無法重新設置引用。

比我聰明的人有什么提示嗎?

如果您無法從operator->返回指針,請按值返回一個幫助程序 class。 使 class 存儲一個KeyValuePair並重載其operator->以返回指向該對的指針。

我的回答使用了與 RedFog 相同的想法,但我試圖讓代碼不那么復雜。

struct Iterator
{
    KeyValuePair operator*() const
    {
        return KeyValuePair(*keys, *values); 
    }

    class ArrowHelper
    {
        KeyValuePair value
      public:
        ArrowHelper(KeyValuePair value) : value(value) {}
        KeyValuePair *operator->() const
        {
            return &value;
        }
    };

    ArrowHelper operator->() const
    {
        return **this;
    }

    int* keys = nullptr;
    int* values = nullptr;
};

迭代器有時會返回一個臨時的 object 作為“引用”,但是operator->通常需要一個左值來獲取它的指針。 在這種情況下,為了讓operator->工作,我們應該提供指針的包裝器: (C++11 版本)

struct KeyValuePair
{
    KeyValuePair(const int& key, int& value) : key(key), value(value) {}

    const int& key;
    int& value;
private:
    template<typename T>
    struct Helper{
        T ref;
        T* operator->(){ return std::addressof(ref); }
    };
    Helper<KeyValuePair> get(){ return Helper<KeyValuePair>{*this}; }
    friend struct Iterator;
};

struct Iterator
{
    KeyValuePair operator*() { return KeyValuePair(*keys, *values); }

    auto operator->()->decltype((*(*this)).get()){
        return (*(*this)).get();
    }

    int* keys = nullptr;
    int* values = nullptr;
};

如果“參考” object ( KeyValuePair ) 是可復制構造的,它就可以工作。 Helper的構造函數中的副本是必需的,因為臨時KeyValuePair將在返回包裝器后被破壞。

暫無
暫無

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

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