在不区分大小写的情况下无法将 std::wstring 转换为 LPCTSTR std::map

Can't convert std::wstring to LPCTSTR in case-insensitive std::map

我正在尝试实现 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 select 将更有意义的消息放入错误列表。

'bool NOCASECOMPARE_STRUCT::operator ()(LPCTSTR,LPCTSTR) const': cannot convert argument 1 from 'const _Kty' to 'LPCTSTR'
with
[
_Kty=std::wstring
]

如果我更改比较方法的签名以接受 std::wstring 个参数,这可以解决问题,但参数 2 无法转换。我想我可以将签名更改为每个签名之一,但希望使我的代码更通用。

问题:

  1. 为什么 std::wstring 不能转换为 LPCTSTR(我使用的是 Unicode 版本)?

  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().