簡體   English   中英

我怎樣才能返回`地圖<k, v> ::迭代器? (`map` class 擴展了`std::map`)</k,>

[英]How can I return `map<K, V>::iterator`? (`map` class extends `std::map`)

I making a custom map class ( kc::map ) that extends std::map , and I want to add at_index() , and I need to return map<K, V>::iterator . 但是當我返回map<K, V>時,會發生此錯誤: error: invalid use of incomplete type 'class kc::map<K, V>'

namespace kc
{
    template<typename K, typename V> class map : public std::map<K, V>
    {
        public:
            using std::map<K, V>::map;
            map<K, V> get_value()
            {
                return *this;
            }
            map<K, V>::iterator at_index(int index)
            {
                map<K, V> m = get_value();
                for (int i = 0; i < index; i++)
                {
                    m.erase(m.begin());
                }
                return m.begin();
            }
    };
};

您可以返回std::map<K,V>::iterator 這將使您的代碼編譯,但迭代器將無效。 get_value返回一個副本, mat_index的本地,並在 function 返回時被銷毀。

從標准容器公開繼承很少是一個好主意。 標准容器不能被繼承(例如它們沒有虛擬析構函數)。 您可以將at_index編寫為算法:

#include <map>
#include <iostream>

template <typename IT>
IT get_at_index(IT begin,IT end,unsigned index){
    if (std::distance(begin,end) < index) return end;
    return std::next(begin,index);
}


int main() {
    std::map<int,int> m{{1,1},{2,2},{3,3}};
    auto it = get_at_index(m.begin(),m.end(),1);
    if (it != m.end()) std::cout << it->first << " " << it->second << "\n";

    it = get_at_index(m.begin(),m.end(),5);
    if (it == m.end()) std::cout << "index 5 is out of range\n";
} 

但是, std::map意味着通過索引訪問。 推進地圖迭代器相當昂貴。 如果您想要一個可以按索引訪問的鍵值對容器,請考慮改用std::vector<std::pair<K,V>>

忽略代碼的真正問題(不建議從標准容器派生,並且at_index將懸空迭代器返回到本地 object m )以獲取要編譯的代碼,您有兩個選擇。

  1. 在 class 中,您不需要在 class 的成員前面加上 class 名稱。 由於iterator不是 class 成員,您需要先添加它,然后一個不合格的iterator才能工作:
using iterator = typename std::map<K, V>::iterator;
iterator at_index(int index)
  1. 您可以直接使用std::map::iterator
typename std::map<K, V>::iterator at_index(int index)

如果您實際上想要做的是在std::map中獲取第 i 個項目,這將起作用:

#include <map>
#include <stdexcept>
#include <iostream>

namespace kc
{
    template<typename K, typename V> class map
    {
        private:
            std::map<K, V> impl;

        public:
            using iterator = typename std::map<K, V>::iterator;
            using value_type = typename std::map<K, V>::value_type;

            std::pair<iterator, bool> insert( const value_type& value )
            {
                return impl.insert(value);
            }
           
            iterator at_index(int index)
            {
                if (index >= impl.size())
                {
                    throw std::invalid_argument("index out of range");
                }
                auto it = impl.begin();
                std::advance(it, index);
                return it;
            }
    };
};

int main()
{
    kc::map<int, int> m;
    m.insert({1, 1});
    m.insert({2, 2});
    m.insert({3, 3});
    std::cout << m.at_index(2)->second;
}

暫無
暫無

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

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