Но я столкнулся с проблемой, которую не знаю, как решить:
Я устал от бедности поддержка Unicode для C++, они создали char8_t, но это всего лишь своего рода uint8_t, который не может обрабатывать многобайты.... и не говоря уже о сломанных u8string, u8string_view и других "stl Basic_string": они не обеспечивают границы utf-8, вы можете создать подстроку, заканчивающуюся в середине последовательности utf8 или начинающуюся в середине другой или и то, и другое....
поэтому я пишу небольшую библиотеку, чтобы правильно обрабатывать ее, соблюдая концепцию «кодовой точки»: у меня есть u8CodepointView, u16CodepointView, u32CodepointView, которые позволяют получать доступ к кодовым точкам без риска разбить многобайты и позволяют проверять. Они доступны только для чтения без копирования. Это дочерний класс базового абстрактного класса utfCodepointView
тогда у меня такой же, но изменяемый: u8Codepoint... u8string.... весь доступ для чтения вынужден проходить через *View, чтобы избежать сломанного текущего дизайна stl string_view и строки, которые дублируют большую часть доступа (но это нормально, поскольку концепция представления появилась позже из-за неэффективности концепции строки). Также я реализовал способ использования обычного API C++ (cout, cin....), поскольку строка, которая не отображается, бесполезна. поэтому мой тип можно безопасно явно привести к std::string и другим типам C++ stl.
проблема в том, что я хочу, чтобы utfStringView принудительно реализовывал некоторый API, а также реализовывал некоторые общие функции, которые используют указатель/ссылку на этот базовый класс для работы с u8string, u16string, u32string, не заботясь о том, что позади.... сравнение строк, REAL сравнение строк, например, u8string и u16string, изменение содержимого строки... и т. д... в большинстве случаев преобразование типов Appart, мне не нужно беспокоиться, если это utf8 utf16 utf32(ucs) позади... в конце все они представляют собой последовательность кодовых точек.
некоторые из этих функций
Код: Выделить всё
class utfStringView {
public :
virtual utfCodepointView operator[] (const cpidx &aIdx) = 0;
virtual utfStringView substr(const cpidx& aStart, size_t aCount) = 0;
};
возьмем, например,
Код: Выделить всё
virtual utfCodepointView operator[] (const cpidx &aIdx) = 0;
поэтому, если я хочу получить размер кодовой точки utf-8 шириной 3 байта в позиции 10 строка, выполняющая lString[10].size(). Мне нужно использовать ковариантный тип возврата: если класс utfCodepointview не был чисто абстрактным классом, возвращаемое значение будет вызывать только utfCodepointview::size(), а не u8CodepointView::size(). И поскольку я сделал его абстрактным, я не могу создать экземпляр объекта этого типа.
поэтому мне придется двигаться чтобы
Код: Выделить всё
virtual utfCodepointView* operator[] (const cpidx &aIdx) = 0;
Код: Выделить всё
virtual utfCodepointView& operator[] (const cpidx &aIdx) = 0;
и возврат ссылки... на что? объект может быть только локальной переменной, поэтому уничтожается при возврате оператора.... я не могу сделать его членом, потому что он не будет потокобезопасным, иначе мне придется защищать его с помощью мьютекса.... и снова потеряю всю эффективность....
то же самое происходит с функцией substr...
единственное решение, которое я вижу, - это сделать utfStringView шаблоном... и мне это не нравится....
Код: Выделить всё
template
class utfStringView
{
public:
constexpr virtual BaseCodepoint operator[] (const cpidx &aIdx) = 0;
constexpr virtual BaseSTring substr(const cpidx& aStart, size_t aCount) = 0;
}
кстати, я перешел на c++23, потому что мне нравится constexpr.... и некоторые действительно хорошие функции constexpr есть только в c++23.... Итак, если есть что-то, что меня спасает в стандарте и о чем я не знаю.... Я не ограничен версией стандарта...
поэтому мой вопрос: есть ли способ сделать это без шаблона? сохраняя полиморфизм и позволяя мне работать со строками, не заботясь о том, что за этим стоит....
спасибо и с уважением
Подробнее здесь: https://stackoverflow.com/questions/798 ... ant-return
Мобильная версия