[英]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
返回一個副本, m
是at_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
)以獲取要編譯的代碼,您有兩個選擇。
iterator
不是 class 成員,您需要先添加它,然后一個不合格的iterator
才能工作:using iterator = typename std::map<K, V>::iterator;
iterator at_index(int index)
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.