У меня есть проблема с дополнительным параметром функции в C++
То, что я пытаюсь сделать, должно записать функцию с дополнительным параметром, который передается ссылкой, так, чтобы я мог использовать его двумя способами (1) и (2), но на (2) я действительно не забочусь о том, что является значением mFoobar
.
Я попробовал такой код:
void foo(double &bar, double &foobar = NULL)
{
bar = 100;
foobar = 150;
}
int main()
{
double mBar(0),mFoobar(0);
foo(mBar,mFoobar); // (1)
cout << mBar << mFoobar;
mBar = 0;
mFoobar = 0;
foo(mBar); // (2)
cout << mBar << mFoobar;
return 0;
}
но это отказывает в
void foo(double &bar, double &foobar = NULL)
с сообщением:
error: default argument for 'double& foobar' has type 'int'
Действительно ли возможно решить его без перегрузки функции?
Аргумент по умолчанию (изменяемой) ссылки должен быть l-значением. Лучшее, что я могу придумать без перегрузки, это
static double _dummy_foobar;
void foo(double &bar, double &foobar = _dummy_foobar)
Почему вы не можете использовать перегрузку функций? Наверняка это самое простое решение проблемы?
void foo(double &bar, double &foobar)
{
bar = 100;
foobar = 150;
}
void foo(double &bar)
{
double foobar = 0.0;
foo(bar, foobar);
}
Не используйте ссылки для необязательных параметров. Не существует понятия ссылки NULL: ссылка - это всегда псевдоним конкретного объекта.
Возможно, посмотрите на boost::optional
или std::experimental::optional
. boost::optional
даже специализирован для ссылочных типов!
void foo(double &bar, optional<double &> foobar = optional<double &>())
Вы можете сделай этот безумный способ:
void foo(double &bar, double &foobar = (*(new double())))
PS - Я знаю, что это неприятно, но свой путь. Также не оставляйте утечек памяти! :))
Другой способ сделать это - использовать указатели вместо ссылок. Это обеспечивает нужную семантику без перегрузки. (Лично я бы, наверное, выбрал перегрузку.)
void foo(double* bar, double* foobar = 0)
{
if (bar) *bar = 100;
if (foobar) *foobar = 150;
}
// ...
foo(&mBar, &mFoobar);
// ...
foo(&mBar);
// ...