将lower_bound与vector <pair <string,double =“”>&gt; </pair <string,>一起使用时出错

时间:2013-11-25 16:48:13

标签: c++ vector stl stdstring lower-bound

我有一个缓存的实现,定义如此;

std::vector<TEntryPair>    m_listEntries;

TEntryPair定义为;

typedef std::pair<std::string, FILETIME> TEntryPair;

将新记录插入缓存时,我使用std::lower_bound在缓存中找到插入排序的正确位置,如下所示;

void AddCacheEntry(std::string const& strResourceName, FILETIME const& fTime)
{
    auto it = std::lower_bound(std::begin(m_listEntries),
                               std::end(m_listEntries),
                               strName);

    m_listEntries.insert(it, std::make_pair(strName, fTime));
}

新条目根据std::string参数进行排序,第二个值基本上是元数据。

在尝试插入新记录时,我为std::lower_bound定义了以下运算符;

bool operator < (std::string const& str, TEntryPair const& rhs)
{
    return str < rhs.first;
}
bool operator < (TEntryPair const& lhs, std::string const& str)
{
    return lhs.first < str;
}

现在一切正常,直到我不得不将TEntryPair的定义更改为以下内容;

std::pair<std::string, double>

有人可以解释为什么在使用std::pair<std::string, double>而不是std::pair<std::string, FILETIME>时无法使用我定义的运算符吗?

编译器给出以下错误;

Error   9   error C2676: binary '<' : 'std::pair<_Ty1,_Ty2>' does not define this operator or a conversion to a type acceptable to the predefined operator  c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   3   error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'std::pair<_Ty1,_Ty2>' c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   7   error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::pair<_Ty1,_Ty2>'    c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   2   error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::pair<_Ty1,_Ty2>'   c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   4   error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::pair<_Ty1,_Ty2>' c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   5   error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'std::pair<_Ty1,_Ty2>'   c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   8   error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string' c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   6   error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::pair<_Ty1,_Ty2>'  c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736
Error   1   error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'std::pair<_Ty1,_Ty2>' c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm    2736

顺便说一句,我可以定义以下内容并编译/运行代码而不会出现任何错误;

struct STemp
{
    double m_Value;
}

typedef std::pair<std::string, STemp> TEntryPair;

似乎只是“基本”类型有问题吗?

1 个答案:

答案 0 :(得分:3)

罪魁祸首似乎是c ++名称解析(具体地说,依赖于参数的查找)与预定义的运算符&lt;在标准库中。

如果TEntryPair完全位于标准库中,则运算符&lt;在您的顶级命名空间中将找不到(对于运算符&lt;在命名空间std之外没有参数,因此只有名称空间std将被考虑用于参数依赖查找)。

虽然标准明确声明不允许在命名空间std中重载函数,但我能找到的问题的唯一解决方案是将运算符&lt;在命名空间std中,因为你正在调用operator&lt;来自命名空间std中,所有参数都属于命名空间std。

对于符合标准的解决方案,您可能需要定义自己的类而不是使用std :: pair。

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

typedef double MyType;

struct TEntryPair {
    std::string first;
    MyType second;
};

bool operator < (std::string const& str, TEntryPair const& rhs)
{
    return str < rhs.first;
}
bool operator < (TEntryPair const& lhs, std::string const& str)
{
    return lhs.first < str;
}

std::vector<TEntryPair>    m_listEntries;

void AddCacheEntry(std::string const& strResourceName, MyType fTime)
{
    auto it = std::lower_bound(std::begin(m_listEntries),
                               std::end(m_listEntries),
                               strResourceName);
}

int main() { }