Можно ли использовать результат вызова функции в качестве значения параметра по умолчанию? - PullRequest
6 голосов
/ 15 октября 2008

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

Ответы [ 8 ]

7 голосов
/ 15 октября 2008

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

int foo(int x, int y);

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

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

7 голосов
/ 15 октября 2008

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

6 голосов
/ 15 октября 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
}

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

6 голосов
/ 15 октября 2008

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

4 голосов
/ 15 октября 2008

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

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

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

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

2 голосов
/ 15 октября 2008

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

1 голос
/ 15 октября 2008

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

0 голосов
/ 15 октября 2008

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

класс Фу { общественности:

static int bar (); };

Тогда вы бы заявили:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...