2008-10-14 1 views
6

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

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

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

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

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

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

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

Где БАЗ функция, принадлежащая к объекту, который не был реализованным в файле заголовка.

+0

AFAIK это относится к C++ не C (C не поддерживает значения по умолчанию). – Motti 2008-10-14 20:57:28

ответ

6

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

+0

Действительно? Я никогда бы не подумал. – Dima 2008-10-14 20:49:29

+0

Lol. Я проигнорировал это как явно неправильное, прежде чем попробовать его сам. – 2008-10-14 20:54:53

1

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

7

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

int foo(int x, int y);

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

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

6

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

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 
} 

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

0

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

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

статический ИНТ-бар(); };

Тогда вы бы объявить:

Int Foo (Int х, Int у = Foo :: бар());

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

2

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

4

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

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

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

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

Смежные вопросы