Не удается преобразовать std :: wstring в LPCTSTR в std :: map без учета регистра - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь реализовать регистронезависимую версию 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
]

Если Iизмените подпись метода сравнения, чтобы она принимала std::wstring аргументов, что решает проблему, но тогда аргумент 2 не может быть преобразован. Я полагаю, что могу изменить подпись на одну из них, но надеялась сделать мой код более универсальным.

Вопросы:

  1. Почему нельзя std::wstringпреобразовать в LPCTSTR (я использую сборку Unicode)?

  2. Есть ли обходной путь без изменения сигнатуры метода сравнения?

1 Ответ

2 голосов
/ 01 октября 2019

Ваш оператор сравнения должен принять два 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().

...