Базовые строковые литералы быстрее или лучше обрабатываются во время компиляции?
просматривая проект C++14 / C++1y (n3690), я заметил введение basic_string
litertal суффиксы в разделе §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);
}
Итак, просто использование тот же конструктор. И я предполагаю, что это должно быть сделано во время выполнения, я ошибаюсь?
Edit: As Никол Болас указал правильно ниже моего примера делает не используйте тот же конструктор, но с дополнительной длиной , что, очевидно, очень полезно для конструкции. Это оставляет у меня вопрос: лучше ли компилятору помещать строковые литералы в ПЗУ или что-то подобное во время компиляции?
3 ответов
- есть ли возможность быть быстрее во время выполнения с литералами basic_string?
как уже говорилось, длина строки известна и автоматически передается конструктору.
- является ли моя "наивная" реализация полностью неправильной?
нет, это правильно.
- может ли макет данных в ПЗУ отличаться от литералов basic_string или любого другого разница во время компиляции и во время выполнения?
вероятно, нет, потому что соответствующий basic_string
конструктор не constexpr
so не будет иметь права на статическую инициализацию, поэтому, вероятно, не может быть помещен в ПЗУ и должен быть сделан во время выполнения.
Итак, просто использование одного и того же c'Tor.
ок, давайте посмотрим, как это будет выглядеть:
string fromLit = "A fabulous string"s;
string fromBare = string("A fabulous string");
увидеть что-нибудь отсутствует в fromBare
? Позвольте мне объяснить вам:--11-->
string fromBare = string("A fabulous string"/*, NOTHING*/);
Да, вы не можете получить длина строки без... получение длины. Что означает, что fromBare
придется перебирать литерал, чтобы найти символ. Во время выполнения.
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;
), второй-еще короче. Но это ясно, что происходит.
он обеспечивает большую безопасность во время компиляции.
считают как вы строите строку std::со встроенным нулем?
единственный способ построить std::string
из строкового литерала, содержащего нулевой символ, следует либо указать размер строкового литерала (подверженного ошибкам), либо использовать initializer_list
синтаксис (подробный) или сделать какой-то цикл с несколькими вызовами push_back
(еще более подробно). Однако с помощью конструктора literal размер автоматически передал вам, удалив возможный источник ошибки.