为模板中的搜索创建虚拟数据

时间:2015-09-09 09:32:39

标签: c++ templates stl

我正在尝试使用矢量实现地图。我陷入了查找功能,因为我使用的是带有键和值的结构,而搜索用户只会提供密钥,我必须在值字段中使用虚拟对象,因为它是模板,所以我目前无法做到这一点。

帮助表示赞赏。 :)

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

//coll.insert(std::make_pair("otto",22.3));
using namespace std;

template<class T1, class T2>
class MyMap
{
    protected:
    struct mapNode
    {
        T1 key;
        T2 value;

        //Ctor
        mapNode(T1 t1, T2 t2): key(t1), value(t2)
        {
        }

        //getters
        const T1& first() const
        {
            return key;
        }

        const T2& second() const
        {
            return value;
        }

        //operators
        bool operator==(const mapNode& rhs)const
        {
            return key == rhs.key;
        }

        bool operator<(const mapNode& rhs) const
        {
            return key < rhs.key;
        }

        mapNode& operator=(const mapNode& rhs)
        {
            key = rhs.key;
            value = rhs.value;
        }
    };

    //data
    vector<mapNode> TheMap;

    public:

    void insert(const T1& k, const T2& v)
    {
        mapNode mn(k, v);
        TheMap.push_back(mn);
    }

    int size() const
    {
        return TheMap.size();
    }

    const T1& getKeyAt(int i) const
    {
        return TheMap[i].first();
    }

    const T2& getValueAt(int i) const
    {
        return TheMap[i].second();
    }

    mapNode& find(const T1& key) const
    {
        //create the data type first needed for searching.
        mapNode tmp(key, ); //This is the issue.

        typename vector<mapNode>::const_iterator pos;
        find(TheMap.begin(), TheMap.end(), key);
        //if(pos != TheMap.end() )
            //return *pos;
    }
};

int main()
{
    MyMap<int, string> m_MyMap;
    m_MyMap.insert(1, "abc");
    m_MyMap.insert(2, "def");
    m_MyMap.insert(3, "ghi");

    for(int i = 0; i < m_MyMap.size(); i++)
    {
        cout<<m_MyMap.getKeyAt(i)<<":"<<m_MyMap.getValueAt(i)<<endl;
    }

    m_MyMap.find(2);

    return 0;

}

1 个答案:

答案 0 :(得分:0)

使用find_if是一个好主意。

为此,您需要一个功能,例如带有重载成员的struct。将以下结构添加到您的类中,就像使用mapNode:

一样
struct HasKey
{
public:
  explicit HasKey( const T1& key )
  { m_key = key; }
  inline bool operator()( const mapNode& node ) const
  { return node.first() == m_key; }
private:
  T1 m_key;
};

正如我在评论中写的那样,将引用返回给局部变量并不是一个好主意,所以我修改了你的find方法:

T2 find(const T1& key) const
{
  vector<MyMap<T1,T2>::mapNode>::const_iterator it = 
    find_if(TheMap.begin(), TheMap.end(), HasKey( key ) );

  if ( it == TheMap.end() )
    throw std::runtime_error( "The map does not contain searched key!" );
  else
    return it->second();
}

我使用异常解决了错误部分,这意味着您需要将find调用包装在try catch块中:

string val;
try 
{ val = m_MyMap.find(2); } 
catch (std::exception &e)
{ std::cout << e.what() << std::endl; return 1; }

std::cout << "Searching for key (" << 2 << ") results in (" << val << ")!" << std::endl;
return 0;

Afaik,我建议返回一个迭代器或const_iterator,以便您可以轻松检查它是否指向结尾,但这当然是不可能的,如果mapNode类型受到保护且您的MyMap必须提供end()方法返回迭代器或const_iterator的TheMaps end()迭代器。

此外,您的operator =必须在结束时返回* this才能工作。