Быстрая настройка: я хочу передать строки в моей программе в виде указателя и размера. У меня есть класс String и пользовательский литерал для построения литеральных строк:
struct String { const char *ptr; size_t sz; };
inline constexpr String operator "" _string(const char *s, size_t sz) {
return {s, sz};
}
int main() {
auto s = "hello"_string;
s.ptr[0]; //<-- is this access guaranteed to work?
}
Указывает ли стандарт, что аргумент, передаваемый моему пользовательскому литеральному оператору, имеет статическую длительность? то есть приведенный выше код фактически эквивалентен написанию:
int main() {
String s{"hello", 5};
}
или компилятору / компоновщику разрешено оставлять меня с висящим указателем, когда я использую пользовательский литерал?
(В разделе 2.13.8 N4527, похоже, ничего не сказано о предмете класса хранения аргумента для определяемых пользователем строковых литеральных операторов. Любые указатели на соответствующие разделы стандарта будут приветствоваться.)
Из [lex.ext]:
Если L является определяемый пользователь строка-буквальная, позволять ул быть буквальный без его уд-суффикс и разреши Len быть числом
кодовые единицы в ул (то есть его длина, исключая завершающий нулевой символ). БуквальныйL
рассматривается как вызов
формы:operator "" X (str , len )
Из [lex.string]:
Оценка Строка литерала приводит к строковому литералу с статическая продолжительность хранения, инициализируется из заданных символов, как указано выше.
Так:
"hello"_string;
эквивалентно:
operator "" _string("hello", 5)
Как "hello"
это Строка литерала, он имеет статическую длительность хранения, поэтому у вас не будет висящего указателя.