Как обрабатывать значение, которое может быть std::string или std::wstring

У меня есть код, который читает файл и выясняет, Unicode это или нет. В зависимости от этого я хотел бы иметь пользовательский объект, который будет содержать содержимое файла как wstring или string и иметь возможность выполнять манипуляции со строками.

Я подумал, что могу просто иметь базовый класс с двумя производными классами, представляющими широкие и узкие строки, или даже базовый класс для string и один производный для wstring. Что-то типа:

class CustomString
{
public:
   static CustomString *methodFactory(bool _unicode);
   std::string Value;

}

class NarrowString : public CustomString
{
public:
   SingleByte(std::string _value);
   std::string Value;
}

class WideString : public CustomString
{
public:
   WideString (std::wstring _value);
   std::wstring Value
}

С чем у меня больше проблем, так это с методами манипулирования строками, скажем, мне нужны .replace, .length и .substr, как я могу их реализовать? Нужно ли мне использовать шаблоны?

virtual T replace(size_t _pos, size_t _len, const T& _str);

Или иметь два метода для каждого типа и переопределять их в производных классах?

virtual std::string replace(size_t _pos, size_t _len, const std::string& _str)
virtual std::wstring replace(size_t _pos, size_t _len, const std::wstring& _str)

Пример того, как будет выглядеть интерфейс с использованием шаблонов и без наследования:

class CustomString
{
public:
    CustomString();
    CustomString(bool _unicode);

    template <typename T>
    T get();

    template <typename T>
    T replace(size_t _pos, size_t _len, const T& _str);

    long length();

    template <typename T>
    T substr(size_t _off);

    template <typename T>
    T append(const T& _str);

    template <typename T>
    T c_str();

private:
    std::wstring wValue;
    std::string nValue;
    bool unicode;

};

}


person Perbert    schedule 21.01.2016    source источник
comment
Вам нужно использовать шаблоны   -  person Jonathan Mee    schedule 21.01.2016
comment
Я бы не стал писать новые классы. Я бы написал общий код. То есть вам все равно, есть ли у вас строка или wstring. Все, что вас волнует, — это операции, которые вы можете выполнять с вашим объектом. Оба класса поддерживают одни и те же операции.   -  person bolov    schedule 21.01.2016
comment
Почему бы не всегда хранить содержимое как wstring плюс флаг, указывающий, был ли оригинал Unicode или нет?   -  person Martin Bonner supports Monica    schedule 21.01.2016
comment
Как будет выглядеть интерфейс пользовательского объекта?   -  person Martin Bonner supports Monica    schedule 21.01.2016
comment
@MartinBonner при чтении содержимого файла должно быть приведение, чтобы иметь возможность хранить их в строке или wstring, например. если 16-битные символы; content = ((wchar_t*)pData) где pData — массив байтов (беззнаковый символ). Я не смог бы преобразовать pData в wstring, если бы он был 8-битным без какого-либо преобразования, и эти преобразования могут быть проблематичными, особенно в Windows   -  person Perbert    schedule 21.01.2016
comment
Да, вам нужно конвертировать, но я не думаю, что это должно быть сложно. Просто назначьте элемент за элементом. Для символов, отличных от ASCII (на данный момент игнорируйте EBCDIC), это, вероятно, не даст вам правильного широкого символа (в зависимости, например, от кодовой страницы). Но если вы не забудете присвоить обратно узкому символу перед отображением, то все будет хорошо. Нам действительно нужно знать, каков интерфейс вашего пользовательского объекта.   -  person Martin Bonner supports Monica    schedule 21.01.2016
comment
Спасибо, я посмотрю на это. Пользовательский объект не был создан, моя идея заключалась в том, чтобы в вопросе было что-то вроде объекта CustomString.   -  person Perbert    schedule 21.01.2016
comment
Прости. Не ясно. Я имел в виду, каким будет интерфейс вашего пользовательского объекта будет.   -  person Martin Bonner supports Monica    schedule 21.01.2016
comment
Я обновил вопросы с примером   -  person Perbert    schedule 21.01.2016


Ответы (1)


Я предлагаю сделать это в другой форме:

enum class Encoding{
   UTF8,
   UTF16
};

Encoding readFile(const char* path, std::string& utf8Result,std::wstring& utf16result);

теперь прочитайте файл в правильный объект и верните правильную кодировку в качестве результата. использование этой функции может написать общий код вокруг этой функции с обобщением шаблона вокруг std::basic_string:

template <class T>
void doNext(const std::basic_string<T>& result){/*...*/}

std::string possibleUTF8Result;
std::wstring possibleUTF16Result;
auto res = readFile("text.txt",possibleUTF8Result,possibleUTF16Result);
if (res == Encoding::UTF8){
  doNext(possibleUTF8Result);
} else { doNext(possibleUTF16Result); }

* примечание: wstring — это utf16 в Windows и utf32 в Linux.

person David Haim    schedule 21.01.2016