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





да. То, что вы написали, работает.
Действительно? Никогда бы не подумал.
Ржу не могу. Я отклонил это как заведомо неправильное, прежде чем попробовать сам.
Программировал на C++ 8 лет и не знал этого!
Я все время узнаю что-то новое о C++ :-)
Иди разберись! Это действительно работает. Аргументы по умолчанию в функциях C++
В этом контексте должно быть вполне допустимо вызывать глобальную функцию или ссылаться на глобальный объект, пока объявление функции / объекта находится в области видимости. Это может быть, а может и не быть целесообразным (с точки зрения хорошего дизайна), но оно должно работать.
Я бы использовал две перегруженные функции:
int foo(int x, int y);
int foo(int x){return foo(x,bar);}
Если вы разрешите встроенную функцию пересылки, то потеря производительности, скорее всего, будет минимальной до нуля. Если вы сохраните его тело вне строки в файле без заголовка, это может привести к снижению производительности (вероятно, будет небольшим), но гораздо больше гибкости в реализации и меньшего связывания.
Предложение об использовании перегруженных функций - это хорошо, но код в вопросе работает как есть.
Что плохого в том, чтобы просто удалить необязательный параметр в первом объявлении и предоставить перегрузку с одним параметром?
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()
);
чтобы позволить клиентам переопределять поведение в конструкторе класса. Пригодился для условного поведения, которое сказывалось на производительности переводчика ...
AFAIK это актуально для C++, а не C (C не поддерживает значения по умолчанию).