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

Есть ли хороший метод для написания заголовков функций 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 — это функция, принадлежащая объекту, который не был создан в заголовочном файле.


person TJ Seabrooks    schedule 14.10.2008    source источник
comment
Насколько мне известно, это относится к С++, а не к C (C не поддерживает значения по умолчанию).   -  person Motti    schedule 15.10.2008


Ответы (8)


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

person Dima    schedule 14.10.2008

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

int foo(int x, int y);

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

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

person Tim Sharrock    schedule 14.10.2008
comment
Предложение по использованию перегруженных функций хорошее, но код в вопросе работает как есть. - person Charlie; 15.10.2008

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

person Lev    schedule 14.10.2008
comment
Действительно? Я никогда бы не подумал. - person Dima; 15.10.2008
comment
Ржу не могу. Я проголосовал за это как за очевидно неправильное, прежде чем попробовать это сам. - person ; 15.10.2008
comment
Программировал на С++ 8 лет и не знал этого! - person Justsalt; 15.10.2008
comment
Я постоянно открываю для себя что-то новое о C++ :-) - person Lev; 15.10.2008

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

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
}

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

person user21714    schedule 14.10.2008

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

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

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

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

person Don Wakefield    schedule 14.10.2008

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

person Paul Nathan    schedule 14.10.2008

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

person Charlie    schedule 14.10.2008

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

класс Foo { общедоступный:

статическая целая полоса(); };

Затем вы должны объявить:

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

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

person Community    schedule 14.10.2008