#c #string #c 11 #curly-braces
#c #строка #c 11 #фигурные скобки
Вопрос:
У меня есть функция, которая принимает std::stringamp;
:
void f(std::stringamp; s) { ... }
У меня есть const char*
который должен быть входным параметром для этой функции. Это работает:
const char* s1 = "test";
std::string s2{s};
f(s2);
Это не:
const char* s1 = "test";
f({s1});
Почему это невозможно? Забавно то, что CLion IDE не жалуется, но компилятор:
no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘std::basic_string<char>amp;’
Комментарии:
1. Почему вы ожидаете, что это сработает?
2. Функция ожидает строку по ссылке, а ваш второй вариант этого не делает. Однако в вашем первом примере
s1
это совершенно не нужно, учитывая ваш пример:std::string s2 = "test";
3. Забавно то, что CLion IDE не жалуется, но компилятор: — CLion не является компилятором. Компилятор выигрывает.
4. Если вы подумаете, что это
const char*
неstd::string
так, то для того, чтобы это вообще работало, для передачи в функцию потребуется создать новую временную строку. Но функция изменяет передаваемую вами строку!! Поэтому он не примет временный. Неконстантная ссылка не будет привязываться к временным файлам.5. Если вам нужна неконстантная ссылка, вы все равно не сможете передать временную.
Ответ №1:
Это не имеет ничего общего с построением std::string
из char const*
.
f
ожидает значение lvalue для строки, и, создавая временный экземпляр на месте, вы предоставляете значение rvalue, которое не может быть привязано к неконстантной ссылке lvalue. f(string{})
так же недопустимо.
Комментарии:
1. Ну,
f
ожидает значение lvalue . Использование ссылочного параметра lvalue — это способ, которым вы выражаете это в C , но это не означает, что «f ожидает ссылку».2. @KerrekSB Я не уверен, что понимаю. Я думал, что функция ожидает ссылку на значение lvalue, и если вы передаете значение lvalue, ссылка привязывается к нему.
3. На самом деле вы не можете «ожидать ссылку». Функции вызываются с аргументами, аргументами являются выражения, а выражения никогда не являются ссылками. Важно то, что выражение является значением lvalue. Ссылки — это способ рассказать о значениях lvalues.
4. @KerrekSB Хорошо, я изменил формулировку, теперь лучше? Мне придется самому разобраться в этом.
5. Мм, не совсем. Значения ни на что не «ссылаются». Дело в том, что «f ожидает значение lvalue
std::string
» или, может быть, «значение строки lvalue». Я не знаю лучшего или более простого способа сказать это. Значение lvalue — это просто определенный вид значения.
Ответ №2:
Ваша функция получает неконстантную ссылку, и вы передаете временный объект, для которого требуется копия или параметр ссылки const. Два решения: создать другую функцию для получения объекта в качестве ссылки на rvalue и вызвать другую перегрузку внутри
void f(stringamp;amp; s) { f(s); }
чтобы разрешить временные объекты в качестве параметра или изменить определение вашей функции, чтобы получать любой объект, но в качестве постоянной ссылки
void f(const std::stringamp; s) { ... }
Ответ №3:
Один из вариантов — изменить вашу функцию, чтобы она принимала строку по значению, а не по ссылке. Тогда это сработает. В любом случае, в C 11 иногда предпочтительнее передавать по значению, а не по ссылке.