无法在不区分大小写的std :: map

时间:2019-10-01 20:29:24

标签: c++ stl stdmap

我正在尝试实现std::map的不区分大小写的版本。这就是我到目前为止所拥有的。

struct NOCASECOMPARE_STRUCT
{
    bool operator() (LPCTSTR psz1, LPCTSTR psz2) const
    {
        return _tcsicmp(psz1, psz2) < 0;
    }
};

std::map<std::wstring, int, NOCASECOMPARE_STRUCT> m_IndexLookup;

IColumn* operator[](LPCTSTR pszColumn) const
{
    auto it = m_IndexLookup.find((LPTSTR)pszColumn);
    if (it != m_IndexLookup.end())
        return m_pColumns[it->second];
    ASSERT(FALSE);
    return nullptr;
}

上面的代码产生编译错误。尽管几乎无法读取数百行STL编译错误,但Visual Studio确实选择了一条更有意义的消息来放入错误列表。

  

'bool NOCASECOMPARE_STRUCT :: operator()(LPCTSTR,LPCTSTR)const':无法将参数1从'const _Kty'转换为'LPCTSTR'
          与
          [
              _Kty = std :: wstring
          ]

如果我将compare方法的签名更改为接受std::wstring参数,则可以解决此问题,但是参数2无法转换。我想我可以将签名更改为每个签名,但是希望使我的代码更具通用性。

问题:

  1. 为什么std::wstring不能转换为LPCTSTR(我正在使用Unicode构建)?

  2. 是否存在不更改我的比较方法签名的解决方法?

1 个答案:

答案 0 :(得分:2)

您的比较运算符应采用两个const std::wstring对象作为输入,因为这就是std::map将传递给它的内容。然后,使用c_str()方法并进行比较:

struct NOCASECOMPARE_STRUCT
{
    bool operator() (const std::wstring& sz1, const std::wstring& sz2) const
    {
        const wchar* psz1 = sz1.c_str();
        const wchar* psz2 = sz2.c_str();
        return _tcsicmp(psz1, psz2) < 0;
    }
};

您可以求助于一个内衬,但是通过这种方式进行调试更容易。

搜索时,将参数作为wstring传递:

IColumn* operator[](LPCTSTR pszColumn) const
{
    auto it = m_IndexLookup.find(std::wstring(pszColumn));
    ...

LPCTSTR基本上是const whar*。您不能直接将std::wstring转换为const wchar*,但可以通过c_str()