Литералы basic_string быстрее или лучше обрабатываются во время компиляции?

Просматривая черновик C ++ 14 / C ++ 1y (n3690), я заметил введение basic_string Литеральные суффиксы в разделе §21.7:

inline namespace literals {
inline namespace string_literals {
// 21.7, suffix for basic_string literals:
string operator "" s(const char *str, size_t len);
u16string operator "" s(const char16_t *str, size_t len);
u32string operator "" s(const char32_t *str, size_t len);
wstring operator "" s(const wchar_t *str, size_t len);
}
}

Мои вопросы:

  • Есть ли возможность быть быстрее во время выполнения с basic_string литералы?
  • Моя «наивная» реализация совершенно неправильна?
  • Может ли расположение данных в ПЗУ отличаться от basic_string литералы, или какое-либо другое различие во время компиляции и во время выполнения?

Я знаю, что это позволяет прямое использование строковых литералов следующим образом:

std::string s1 = "A fabulous string"s;

void sfunc(std::string arg);

int main() {
sfunc("argument"s);
}

Но в чем преимущество этого по сравнению с конструктор преобразования string(const char*)?

«Старый» код будет выглядеть так:

std::string s1 = "A fabulous string";  // c'tor string(const char*)

void sfunc(std::string arg);

int main() {
sfunc("argument");   // auto-conversion via same c'tor
}

Насколько я могу видеть реализацию operator "" s() в основном будет выглядеть так:

std::string operator "" s(const char* lit, size_t sz) {
return std::string(lit, sz);
}

Так что, просто использование того же c’tor. И я думаю, что это должно быть сделано во время выполнения, я не прав?

Редактировать: Как Николь Болас правильно указал ниже мой пример делает не используйте тот же конструктор, но тот, который имеет дополнительную длину — что очень полезно для построения, очевидно. Это оставляет для меня вопрос: лучше ли компилятору помещать строковые литералы в ROM или что-то подобное во время компиляции?

8

Решение

  • Есть ли возможность быть быстрее во время выполнения с литералами basic_string?

Как уже говорилось, длина строки известна и автоматически передается в конструктор.

  • Моя «наивная» реализация совершенно неправильна?

Нет, это правильно.

  • Может ли расположение данных в ПЗУ отличаться от литералов basic_string, или от каких-либо других отличий во время компиляции и во время выполнения?

Вероятно, нет, потому что соответствующие basic_string конструктор не constexpr поэтому не будет иметь права на статическую инициализацию, поэтому, вероятно, не может быть помещен в ПЗУ и должен быть выполнен во время выполнения.

6

Другие решения

Так что, просто использование того же c’tor.

Хорошо, давайте посмотрим, как это будет выглядеть:

string fromLit = "A fabulous string"s;
string fromBare = string("A fabulous string");

Смотрите что-нибудь пропавшее в fromBare? Позвольте мне изложить это для вас:

string fromBare = string("A fabulous string"/*, NOTHING*/);

Да, вы не можете получить длина строки без … получения его длины. Который означает, что fromBare придется перебирать литерал, чтобы найти \0 персонаж. Во время выполнения. fromLit не буду; компилятор предоставляет длину строки как параметр, определенный во время компиляции. Любой стоящий компилятор просто вставит длину в исполняемый код.

И даже если это не было случай, это все еще лучше по другим причинам. Учти это:

void SomeFunc(const std::string &);
void SomeFunc(const char *);

SomeFunc("Literal");
SomeFunc("Literal"s);
SomeFunc(std::string("Literal"));

Последние два делают то же самое (за исключением того, что я говорил ранее), но один из них много короче. Даже если вы работаете using std::string (или глупо using namespace std;), второй еще короче. Все же ясно, что именно происходит.

4

Это обеспечивает большую безопасность во время компиляции.

Рассматривать Как вы строите std :: string со встроенным нулем?

Единственный способ построить std::string из строкового литерала, содержащего нулевой символ, либо для указания размера строкового литерала (подверженного ошибкам), используйте initializer_list синтаксис (многословный) или сделать какой-то цикл с несколькими вызовами push_back (еще более многословный). Однако, с помощью литерального конструктора, размер автоматически передается вам, что устраняет возможный источник ошибки.

1
По вопросам рекламы [email protected]