如何使std :: map比较处理多种数据类型?

时间:2012-03-29 22:26:23

标签: c++ data-structures stl

我将整个表存储在std::deque<record *>中,我需要允许用户对任何列上的表进行排序。该表以列表框格式呈现给用户。

每条记录由多个字符串(字符串结构)组成。但是,字段具有不同的类型,即时间(HH:MM:SS),浮点数和字符串,即使它们都存储为字符串。

允许用户对这些列中的任何列进行排序。当用户点击该列时,我将每个记录存储在一个多图中,以便该表以排序的格式显示给用户。

但是,由于列的类型不同,如何编写单个比较方法,以便有效地处理所有这些?

我想到了以下几种方式

  1. 为每种类型使用不同的映射,并为每个映射编写一个比较函数类。
  2. 使用单个地图,使用处理所有三种不同类型的比较类。但是对于每次插入,比较类必须决定类型,并相应地插入。
  3. 有比这两个更好的方法吗?

    示例:

    struct ltDataCompare
    {
    
        bool operator()( const CString& csData1, const CString& csData2)  const
        {
    
            if ( isTimeFormat(csData1) && isTimeFormat(csData1) )
            {
                   // Do time relevant comparision
                }
                else if ( isNumberFormat( csTime1 ) && isNumberFormat(csTime2) )
            {
                double dPrice1 = atof((LPCTSTR)csTime1);
                double dPrice2 = atof((LPCTSTR)csTime2);
    
                return ( dPrice1 < dPrice2);
            }
            return ( csTime1 < csTime2 );
        }
    };
    
    std::multimap<CString,list_record_t*,ltDataCompare> _mapAllRecords; // Used only for sorting
    

2 个答案:

答案 0 :(得分:1)

您无法对mapmultimap进行重新排序 - 一旦插入项目,其位置就会被锁定。最好使用不同的容器,例如vector,并在必要时对其进行排序。

比较类的好处是它允许包含状态。你可以让一个成员使用一些常量或指针来确定使用哪种比较方法。

您可以使用相同的原则来选择要排序的字段。

struct ltDataCompare 
{
    ltDataCompare(int field, int method) : m_field(field), m_method(method) {}
    bool operator()( const record& left, const record& right) const 
    {
        if (m_method == enumTimeFormat)
            return CompareTimes(left[m_field], right[m_field]);
        else if (m_method == enumNumberFormat)
            return CompareNumbers(left[m_field], right[m_field]);
        // ...
    }
    int m_field;
    int m_method;
};

std::sort(table.begin(), table.end(), ltDataCompare(0, enumTimeFormat));

答案 1 :(得分:0)

你可能会更优雅 - 我不知道你会为自己省下任何工作 - 如果你有一个带有&lt;每个类型的运算符。如果你有一个具有虚拟&lt;的超类。然后,您可以将其用作键类型,如

std::multimap< superclass, list_record_t >

现在您可以使用任何子类型作为实际键(只要您保持一致)。 其实我不确定这是更聪明还是更优雅。更聪明通常是一件坏事(因为它意味着更加模糊/不易维护)。如果它减少了代码行数,那通常是件好事。