TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #542 4.12K
Дефолтные и ссылочные параметры

Есть такой паттерн или стиль написания кода, как входные+выходные параметры у функции. Вместо того, чтобы возвращать результат работы функции в возвращаемом значении, его возвращают через ссылочные параметры.

И вот допустим, у нас программист Иннокентий. У него в проекте есть функция, которая хорошо и без нареканий работает и отправляет запрос базе

bool DBConnection::SendQuery(const char* query, 
const DbQueryParams& params = DbQueryParams{});

Если запрос отослан удачно, возвращаем тру, если нет, то фолс.

Строка запроса к базе может содержать плейсхолдеры(это метки в подготовленном запросе, куда будут подставляться актуальные значения параметров), а может и не содержать. Если они есть, то вместе с query передаются и параметры для подстановки в запрос. Если нет, то у нас есть пустое значение по-умолчанию.

Но жизнь течет, все изменяется. Кенни поступила задачка проверять состояние конекшена перед отправкой запроса, возвращать результат проверки наружу и ...(построить какую-то логику на результате).

А в проекте у него используется паттерн с выходными параметрами. Обычно это реализовывается так: в начале в аргументах функции идут все входные параметры и затем все выходные. Вроде как логично.

Он, согласно своему код стайлу, пишет:

bool DBConnection::SendQuery(const char* query, 
const DbQueryParams& params = DbQueryParams{},
DbConnectionState& state);


Реализовал функцию и запустил билд. А он, хромоногий, упал.

Нельзя указывать параметры функции без значения по умолчанию после параметров, имеющих это значение.

Видимо это сделано так, потому что иначе появляется пространство для неопределенности.

Ладно еще в этом случае компилятор видит разные типы и может как-то соотнести 2 и 2. Но например в случае тривиальных типов все не так однозначно. Они могут неявно конвертироваться друг в друга и тут уже распарсить нельзя.

void foo(int i, float j = 5.0, unsigned k);

foo(1, 2); // Невозможно понять, вызвали ли вы foo(1, 5.0, 2) или
например по ошибке передали слишком мало аргументов


Закатив глаза и особо не думая, он исправляет:

bool DBConnection::SendQuery(const char* query, 
const DbQueryParams& params = DbQueryParams{},
DbConnectionState& state = DbConnectionState::OK);


И билд тоже падает! Но теперь уже по другому поводу.

Неконстантные левоссылочные параметры нельзя определять со значениями по-умолчанию.

Причина тут очень простая. Вы не можете создать левую ссылку из значения типа rvalue reference. У объекта должно быть имя, чтобы его можно было присвоить неконстантной левой ссылке. У DbConnectionState::OK имени нет, поэтому и упали.

Выход только один. Нарушать свой код-стайл. Придется пихать параметр DbConnectionState& state либо первым параметром, либо между query и params.

Первый способ вообще в принципе нарушает все негласные соглашения в объявлениях функции среди всех языков.

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

Кенни не придумал ничего лучше и сильно расстроился. Пошел в лес, увидел там машину, сел в нее и сгорел.

А что Иннокентий в принципе мог сделать в этой ситуации? Жду ваших вариантов в комментариях)

Don't worry. All difficulties will pass.

#cppcore
  • 🔥 15
  • ❤ 7
  • ❤‍🔥 7
  • 👍 3
  • 🤷‍♂ 2
  • 🤔 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →