Я пытаюсь сделать утилиту для преобразования строк, так как у меня плохое сочетание интерфейсов, требующих строки в различных контейнерах (char *, std :: string, пользовательский тип строки) и форматов (utf-8, utf-16, utf-32) , Поэтому у меня возникла идея создать оболочку с операторами приведения к различным типам. Как это:
#include <iostream>
#include <string>
struct X {
operator std::string() { return std::string("string x"); }
operator const char *() { return "zstring x"; }
};
X make_x() { return X(); }
int main()
{
std::string y = make_x(); // this works
std::string y(make_x()); // but this does not
y = make_x(); // this does not work either
y = std::string(make_x()); // nor does this, so it's about useless
std::cout << y << std::endl;
return 0;
}
Но проблема в том, что если тип преобразуется в оба char *
а также std::string
, std::string
Конструктор и присваивание будут неоднозначными между этими двумя типами. И я не хочу проходить только char *
потому что строка может быть изначально задана диапазоном, а не как нуль-завершенная, требуя дополнительной копии, чтобы получить нуль-завершенную, а также заставляя встроенные нули не работать.
Так есть ли способ избавиться от них?
Важное примечание: я застрял с некоторыми компиляторами C ++ 03, поэтому ни один оператор приведения не может быть помечен явно.
Явно приведу результат make_x()
так std::string
, const char*
или что-то еще до того, как передать его в качестве аргумента функции, e. г.:
std::string y(static_cast<const char*>(make_x()));
Если вам нужно много делать и считать это многословным, дайте операторам приведения короткие имена:
struct X {
std::string str() { return std::string("string x"); }
const char *cstr() { return "zstring x"; }
};
std::string y(make_x().str());
Если это также неприемлемо, адаптируйте безопасная идиома к вашей цели.
В итоге я создал одного помощника с оператором приведения к любому персонажу (char
, wchar_t
и либо uint16_t
или же uint32_t
в зависимости от того wchar_t
является 32 или 16-битным) типом указателя и другим помощником с оператором приведения к любой basic_string (специализированной для любого из вышеперечисленных, с использованием пользовательских признаков для нестандартных типов). Это не кажется двусмысленным нигде.