C++ std:: string start_with / end_with версии без учета регистра?

В C++20 в std::string добавлены start_with, end_with.

Есть хороший способ, чтобы заставить его быть случай в чувствительный?

Обратите внимание, что производительность имеет значение, поэтому я не хочу, чтобы обе строки (или std::min(len1, len2) части из них).

В отличие от обычных <algorithm> алгоритмы starts_with не имеет перегрузки с компаратором, поэтому я не вижу хорошего способа сделать это.

И я как бы понимаю, что 90+% случаев чувствительны к регистру, и что член fns в C++ избегается, если только он не является чрезвычайно полезным... поэтому я знаю, почему существует это ограничение, мне просто любопытно, можно ли что-то относительно читабельное можно взломать вместе С ++20 без моего ручного вызова std::equal(или равных диапазонов) с настраиваемым компаратором.

3 ответа

Я тоже недавно столкнулся с этой проблемой.

Если вы не возражаете против использования boost, есть функции istarts_with и iends_with .

Они делают именно то, что вам нужно.

Мне было любопытно посмотреть, как работает предложение применить этот ответ. Вот результат.

Код из указанного ответа:

struct ci_char_traits : public char_traits<char> {
    static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
    static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
    static bool lt(char c1, char c2) { return toupper(c1) <  toupper(c2); }
    static int compare(const char* s1, const char* s2, size_t n) {
        while( n-- != 0 ) {
            if( toupper(*s1) < toupper(*s2) ) return -1;
            if( toupper(*s1) > toupper(*s2) ) return 1;
            ++s1; ++s2;
        }
        return 0;
    }
    static const char* find(const char* s, int n, char a) {
        while( n-- > 0 && toupper(*s) != toupper(a) ) {
            ++s;
        }
        return s;
    }
};

typedef std::basic_string<char, ci_char_traits> ci_string;

Там ответ предлагал использовать ci_string вместо того std::string. Здесь мы просто хотим создатьci_views к std::strings:

typedef std::basic_string_view<char, ci_char_traits> ci_string_view;

int main()
{   
    std::string x{"ABCD"};
    std::string y{"abcd"};
    std::cout << ci_string_view{x.begin(),x.end()}.ends_with(ci_string_view{y.begin(),y.end()});
}

Выход:

1

Живой пример

std::mismatch(s1.begin(), s1.end(), s2.begin(), s2.end(), <comparator>)буду делать то, что ты хочешь. Вы должны написать компаратор без учета регистра, но я уверен, что вы сможете это понять.

Другие вопросы по тегам