简体   繁体   中英

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

I'm trying to implement a case-insensitive version of std::map . Here's what I have so far.

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

The code above produces compile errors. While the hundreds of lines of STL compile errors are virtually impossible to read, Visual Studio does select a more meaningful message to put in the error list.

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

If I change the compare method's signature to accept std::wstring arguments, that fixes the problem but then argument 2 can't be converted. I suppose I can change the signature to one of each but was hoping to make my code more general purpose.

Questions:

  1. Why can't a std::wstring convert to LPCTSTR (I'm using a Unicode build)?

  2. Is there a workaround without changing my compare method signature?

Your comparison operator should take two const std::wstring objects as input because that is what std::map will pass to it. From that, use the c_str() method and do your comparison:

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

You could resort to one liners, but doing it this way is easier for debugging.

When searching, pass the argument as a wstring :

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

LPCTSTR is basically const whar* . You can't convert a std::wstring to a const wchar* directly, but you can via c_str() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM