Мне нужно было найти регистронезависимый поиск, и я нашел следующий код, который добился цели
bool ci_equal(char ch1, char ch2)
{
return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}
size_t ci_find(const string& str1, const string& str2)
{
string::const_iterator pos = std::search(str1. begin ( ), str1. end ( ), str2.
begin ( ), str2. end ( ), ci_equal);
if (pos == str1. end ( ))
return string::npos;
else
return pos - str1. begin ( );
}
. Это заставило меня задуматься, что нужно сделать, чтобы сделать эту функцию членом функции 'string', чтобы она можно было бы назвать так:
string S="abcdefghijklmnopqrstuv";
string F="GHI";
S.ci_find(F);
Я понимаю, что есть много проблем с преобразованием регистра в неанглийских языках, но это не тот вопрос, который меня интересует.
Будучи неофитом, я быстро заблудился среди контейнеров и шаблонов.
Есть ли в любом случае, чтобы сделать это? Может ли кто-нибудь указать мне пример чего-то подобного?
std::string
не предназначен для расширения.
Вы можете инкапсулировать std::string в свой класс и установить эти функции-члены в этом классе.
Возможно использование методологии стандартных библиотечных алгоритмов <алгоритм>
может быть полезным. Это не удивило бы пользователей так сильно. : -)
Функции алгоритма в качестве примера.
Я думаю, что большинство более опытных программистов C++ согласятся, что это плохая идея. Если уж на то пошло, std::string
уже имеет слишком много функций-членов, а добавление еще большего числа усугубит плохую ситуацию. Хуже того, если бы вы собирались сделать это, вы, вероятно, сделали бы это путем наследования - но std::string
не предназначен для использования в качестве базового класса, и использование его в качестве базового класса приведет к хрупкому и подверженному ошибкам коду.
Для получения другой идеи о том, как это сделать, вы можете прочитать Гуру недели #29. Прочитайте статью целиком, чтобы получить представление о том, как это сделать, и почему вы, вероятно, не хотите этого делать. В конечном счете, то, что вы имеете сейчас, вероятно, лучший вариант - сохраняйте поиск без учета регистра отдельно от std::string
.
В большинстве случаев достаточно определить функтор . Более конкретно, менее чем компаратор . Преимущество состоит в том, что функтор вместе с немодифицированным классом string
может храниться в контейнерах STL, а STL будет использовать ваши пользовательские функторы для операций.
Это класс с конструктором по умолчанию и перегруженным оператором вызова функции bool operator () (const string & x, const string & y)
, который выполняет сравнение без учета регистра.
Вы также можете определить функтор равенства, в зависимости от ваших потребностей.
Правда, больше нельзя использовать операторы ==
и <
буквально на объектах вашего строкового класса, вместо этого вам нужно будет создать экземпляр функтора и используйте его как вызов функции. Но я не думаю, что в C ++ есть другая альтернатива.
Отредактировано: Я неправильно понял вопрос. Нерелевантная часть ответа удалена.
Отредактировано 2: Пожалуйста, полностью проигнорируйте мой ответ ...