【问题标题】:Create a dummy data for search in templates创建用于在模板中搜索的虚拟数据
【发布时间】:2015-12-05 05:03:34
【问题描述】:

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

感谢您的帮助。 :)

#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;

}

【问题讨论】:

  • 你为什么不直接比较你的 mapNode.key 和密钥呢?我认为您不应该创建虚拟结构。例如,您可以使用 std::find_if
  • 但查找算法将期望结构,因为这是向量包含的内容。
  • 你应该检查 std::find_if。 :)
  • 返回对局部变量的引用不是一个好主意。见stackoverflow.com/questions/6441218/…
  • @Gombat:OP 不返回局部变量的引用,而是取消引用迭代器。

标签: c++ templates stl


【解决方案1】:

使用 find_if 是个好主意。

为此,您需要一个函数,例如具有重载成员的结构。将以下结构添加到您的类中,就像您对 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 才能工作。

【讨论】:

  • 返回 const T2&amp; 没问题(只要我们不在向量中插入/删除元素。)
  • 对。但我仍然建议使用迭代器,因为那时您不需要异常处理。
  • @Gombat:我这里有个问题,当我们将一元谓词传递给 find_if 时,为什么要创建一个单独的结构,难道我们不能也只写一个函数来重载 operator(),这种方法是更好的是,编写结构或在 operator() 函数上。
  • @tan:如何将要搜索的关键变量传递给函数?如果函数可以决定您要搜索的元素,它可以工作,但据我所知,要找到一个特定的值,不知道将其作为常量写入函数,您必须创建一个结构来传递它.
猜你喜欢
  • 1970-01-01
  • 2018-09-06
  • 2012-09-18
  • 2019-01-07
  • 2018-11-29
  • 2014-02-11
  • 2015-12-09
  • 1970-01-01
  • 2019-06-12
相关资源
最近更新 更多