LINUX.ORG.RU

Вопрос новичка по ссылкам в С++

 ,


0

2

20+ лет не писал на C++, недавно пришлось начать снова. Поэтому современный C++ осваиваю потихоньку, когда время позволяет.

В кодовой базе, с которой работаю, есть такой фрагмент кода в тесте:

for (const QString &host : {"localhost", "test"}) {
...
}

Почему-то некоторые компиляторы это компилируют, а некоторые (gcc 11.2) — отказываются.

У меня сомнения - валидный ли это код. На мой взгляд, это комплироваться не должно, но clang, например, компилит без проблем. Или просто gcc 11 — слишком старый?..

Как оно тогда работает, как можно присвоить ссылке на QString обычную C-строку? Бегло погуглил, и кажется, что оно работать не должно, но работает ведь.

QString нет, поэтому std::string.
https://cppinsights.io/s/e8af8c89

{
  const char *const __list21[2]{"localhost", "test"};
  std::initializer_list<const char *> && __range1 = std::initializer_list<const char *>{__list21, 2};
  const char *const * __begin1 = __range1.begin();
  const char *const * __end1 = __range1.end();
  for(; __begin1 != __end1; ++__begin1) {
    const std::basic_string<char> & host = std::basic_string<char>(*__begin1, std::allocator<char>());
  }
}

ox55ff ★★★★★
()
Последнее исправление: ox55ff (всего исправлений: 1)

Код валидный.

Вот это имеет тип std::initializer_list<char const *>

const auto l = {"localhost", "test"};
rumgot ★★★★★
()

Код рабочий, но чё-то попахивает индусокодингом, обычно делают:

const QStringList str_list{"localhost", "test", ...};

for (const auto& it : str_list)
{ ... }
P. S. Ещё лучше использовать по возможности перечисления (enum), а не строки.

Dr64h ★★★
()
Последнее исправление: Dr64h (всего исправлений: 1)
Ответ на: комментарий от ox55ff

Ошибся: не ошибка компиляции, а warning, но у нас включено трактовать все ворнинги как ошибки:

/home/***/Testing/UnitTests/TestWinAdminPrefDlg/TestWinAdminPrefDlg.cpp:27:25: error: loop variable ‘host’ of type ‘const QString&’ binds to a temporary constructed from type ‘const char* const’ [-Werror=range-loop-construct]
   27 |     for (const QString &host : {"localhost", "test"}) {
      |                         ^~~~
/home/***/Testing/UnitTests/TestWinAdminPrefDlg/TestWinAdminPrefDlg.cpp:27:25: note: use non-reference type ‘const QString’ to make the copy explicit or ‘const char* const&’ to prevent copying
cc1plus: all warnings being treated as errors
emorozov
() автор топика
Ответ на: комментарий от emorozov

Это очень странный вопрос. Разные компиляторы - разные предупреждения. Более того, разные версии одного компилятора - разные предупреждения.

slovazap ★★★★★
()
Ответ на: комментарий от Dr64h

Не «обычно». Тут, в зависимости от того как потом используется host возможны как минимум 3 варианта кроме тех что предлагает варнинг. На самом деле вариант с initializer_list тут всегда предпочтительней из-за читаемости, а ещё он позволяет не конструировать ни QString, ни их списки без необходимости.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

а ещё он позволяет не конструировать ни QString, ни их списки без необходимости.

С таким подходом можно вообще не использовать Qt.

Dr64h ★★★
()
Ответ на: комментарий от Dr64h

Без Qt точно не обойтись, т.к. это код GUI приложения (точнее, тестов для него).

emorozov
() автор топика
Ответ на: комментарий от Dr64h

Если это используется только в одном этом месте, то нет смысла два QString конструировать. Запись через список инициализации точно короче.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Это уже кому как нравится, я скорее общий случай описывал, так что закроем тему.

Dr64h ★★★
()
Ответ на: комментарий от Dr64h

Какой-то странный намёк на абсолютизм. Из того что проект использует Qt никак не следует того что не нужно использовать конструкции c++/stl. Я лично считаю что часть кода где используется Qt лучше, наоборот, максимально ограничить.

slovazap ★★★★★
()
Ответ на: комментарий от emorozov

правильно предупреждает — ссылка может возделывать здесь лишнее копирование за счет использования конструктора копирования.

safocl ★★
()
Ответ на: комментарий от slovazap

в общем то сами разработчики qt указывают на тоже самое — заменяют многие самописные сущности на сущности из std:: в новых версиях qt.

safocl ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.