Передача дополнительного параметра ссылкой в C++

У меня есть проблема с дополнительным параметром функции в 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'

Действительно ли возможно решить его без перегрузки функции?

30
задан svick 15 August 2013 в 15:51
поделиться

5 ответов

Аргумент по умолчанию (изменяемой) ссылки должен быть l-значением. Лучшее, что я могу придумать без перегрузки, это

static double _dummy_foobar;
void foo(double &bar, double &foobar = _dummy_foobar)
30
ответ дан 27 November 2019 в 23:03
поделиться

Почему вы не можете использовать перегрузку функций? Наверняка это самое простое решение проблемы?

void foo(double &bar, double &foobar) 
{ 
   bar = 100; 
   foobar = 150; 
}

void foo(double &bar) 
{ 
   double foobar = 0.0;
   foo(bar, foobar);
}
33
ответ дан 27 November 2019 в 23:03
поделиться

Не используйте ссылки для необязательных параметров. Не существует понятия ссылки NULL: ссылка - это всегда псевдоним конкретного объекта.

Возможно, посмотрите на boost::optional или std::experimental::optional. boost::optional даже специализирован для ссылочных типов!

void foo(double &bar, optional<double &> foobar = optional<double &>())
39
ответ дан 27 November 2019 в 23:03
поделиться

Вы можете сделай этот безумный способ:

void foo(double &bar, double &foobar = (*(new double())))

PS - Я знаю, что это неприятно, но свой путь. Также не оставляйте утечек памяти! :))

-5
ответ дан 27 November 2019 в 23:03
поделиться

Другой способ сделать это - использовать указатели вместо ссылок. Это обеспечивает нужную семантику без перегрузки. (Лично я бы, наверное, выбрал перегрузку.)

void foo(double* bar, double* foobar = 0)
{
   if (bar) *bar = 100;
   if (foobar) *foobar = 150;
}

   // ...

   foo(&mBar, &mFoobar);

   // ...

   foo(&mBar);

   // ...
5
ответ дан 27 November 2019 в 23:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: