почему инициализация ссылки успешна с одним конструктором, но не с другим - PullRequest
1 голос
/ 29 февраля 2020

Наш код использовал что-то вроде ниже, чтобы передать константную строковую ссылку:

const char* str = // passed in;
const std::string& sym(str);

Тогда мне нужно исправить это для символа взятия только как первые 5 символов, я сделал:

const std::string& sym(str, 5);

но это вызывает у меня ошибку компиляции:

error: expression list treated as compound expression in initializer [-fpermissive]

Почему я могу вызвать первый конструктор, но не второй?

Ответы [ 2 ]

1 голос
/ 29 февраля 2020

Проверьте документацию для инициализации ссылок [dcl.init.ref / 5] :

Ссылка на тип « cv1 T1 »Инициализируется выражением типа« cv2 T2 »следующим образом ..

В вашем случае

const std::string& sym(str, 5);    

выражение является выражение буйного str, 5. По сути, это то же самое, что если бы вы написали

const std::string& sym = (str, 5);    

, что в обоих случаях сводится к ...

const std::string& sym = 5;

или

const std::string& sym(5);

Насколько я понимаю, стандарт позволяет инициализировать ссылку только одним выражением, а не парой выражений, разделенных запятой.

И нет соответствующего конструктора (который говорит о второй ошибке в вашей демонстрации Godbolt).

В качестве решения вы можете написать:

const std::string& sym{str, 5};

с тех пор, согласно [dcl.init / 17.1] :

Если инициализатором является (не заключенный в скобки) braced-init-list или = braced-init-list , объект или ссылка инициализируется списком .

1 голос
/ 29 февраля 2020

Поскольку язык не позволяет этого.

(...) здесь не вызывает конструкторы std::string, потому что тип вашей переменной не std::string, а ссылка. Вместо этого T &ref(x); - это просто другой способ записи T &ref = x;.

Обратите внимание, что в const std::string& sym(str);, поскольку тип str - это const char *, а не std::string, временный std::string создается и привязывается к ссылке, и его время жизни увеличивается .

Это делает const std::string& sym(str); в основном эквивалентным const std::string sym(str); (но немного более запутанным).

...