Можно ли использовать результат вызова функции в качестве значения параметра по умолчанию?

Есть ли хороший метод для написания заголовков функций C / C++ с параметрами по умолчанию, которые являются вызовами функций?

У меня есть заголовок с функцией:

int foo(int x, int y = 0);

Я работаю с большой базой кода, где многие функции вызывают эту функцию и зависят от этого значения по умолчанию. Это значение по умолчанию теперь нужно изменить на что-то динамическое, и я ищу способ сделать:

int foo(int x, int y = bar());

Где bar () - это некоторая функция, которая генерирует значение по умолчанию на основе некоторых системных параметров. В качестве альтернативы этот прототип функции мог бы выглядеть так:

int foo(int x, int y = baz.bar());

Где baz - это функция, принадлежащая объекту, который не был создан в заголовочном файле.

AFAIK это актуально для C++, а не C (C не поддерживает значения по умолчанию).

Motti 15.10.2008 00:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
1
482
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

да. То, что вы написали, работает.

Действительно? Никогда бы не подумал.

Dima 15.10.2008 00:49

Ржу не могу. Я отклонил это как заведомо неправильное, прежде чем попробовать сам.

Mike F 15.10.2008 00:54

Программировал на C++ 8 лет и не знал этого!

Justsalt 15.10.2008 20:02

Я все время узнаю что-то новое о C++ :-)

Lev 15.10.2008 22:04
Ответ принят как подходящий

Иди разберись! Это действительно работает. Аргументы по умолчанию в функциях C++

В этом контексте должно быть вполне допустимо вызывать глобальную функцию или ссылаться на глобальный объект, пока объявление функции / объекта находится в области видимости. Это может быть, а может и не быть целесообразным (с точки зрения хорошего дизайна), но оно должно работать.

Я бы использовал две перегруженные функции:

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

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

Предложение об использовании перегруженных функций - это хорошо, но код в вопросе работает как есть.

Charlie 15.10.2008 00:54

Что плохого в том, чтобы просто удалить необязательный параметр в первом объявлении и предоставить перегрузку с одним параметром?

int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

Я думаю, что это, как правило, намного чище и гибче, чем попытка использовать какое-то динамическое значение по умолчанию.

Попробуйте сделать bar () статической функцией-членом. Это позволит любой части программы, имеющей такой статический класс в области видимости, получить к нему доступ. Например:

класс Foo { общественность:

статический int bar (); };

Тогда вы заявите:

int foo (интервал x, int y = Foo :: bar ());

Если вам нужны другие объекты, вместо этого передайте экземпляр объекта.

Тангенциально, но мне кажется, что в будущем возникнут проблемы с зависимостью. Я бы пошел с подходом stbuton.myopenid.com.

В стандарте, раздел 8.3.6 (Аргументы по умолчанию), параграф 5, они дают пример, использующий именно этот подход. В частности, он указывает, что аргументы по умолчанию - выражения, поэтому применяется вызов функции, хотя и с такими ограничениями, как поиск имени и совместимость типов.

На моем рабочем месте мы использовали такие подписи:

void An_object::An_object(
  const Foo &a,
  const Bar &b,
  const Strategem &s = Default_strategem()
);

чтобы позволить клиентам переопределять поведение в конструкторе класса. Пригодился для условного поведения, которое сказывалось на производительности переводчика ...

Другие вопросы по теме