Как передать функции параметр по ссылке со значением по умолчанию?
void func(int &i)
void func2(set<int> &s)
и при этом иметь возможность вызывать эти функции без аргументов, чтобы переменной i присваивалось значение по умолчанию, а для s вызывался конструктор, чтобы использовать множество set в теле функции.
Если вы хотите использовать аргумент по умолчанию по ссылке, то этот аргумент должен быть не временным объектом и уже где-то быть определенным на момент вызова функции.
Передача аргумента по неконстантной ссылке предполагает, что этот исходный аргумент будет в функции изменен. Вы не можете передавать по неконстантной ссылке временные объекты.
Поэтому, исходя из условий, указанных в вашем вопросе, скорей всего у вас должны быть две перегруженные функции. Одна функция принимает аргумент по lvalue
-ссылке с конкретно заданным объектом. Вторая функция оибл принимает временный объект по rvalue
-сслке, оибо вместо него использует значение по умолчанию.
Например,
#include <iostream>
void func( int &i )
{
++i;
std::cout << "Inside func( int & ) i = " << i << std::endl;
}
void func( int &&i = int() )
{
++i;
std::cout << "Insde func( int && ) i = " << i << std::endl;
}
int main()
{
int i = 0;
std::cout << "Before func( i ) i = " << i << std::endl;
func( i );
std::cout << "After func( i ) i = " << i << std::endl;
std::cout << std::endl;
i = 0;
std::cout << "Before func() i = " << i << std::endl;
func();
std::cout << "After func() i = " << i << std::endl;
return 0;
}
Вывод программы на консоль:
Before func( i ) i = 0
Inside func( int & ) i = 1
After func( i ) i = 1
Before func() i = 0
Insde func( int && ) i = 1
After func() i = 0
В этой программе, когда в качестве аргумента передается lvalue
, то используется первая функция
void func( int &i )
{
++i;
std::cout << "Inside func( int & ) i = " << i << std::endl;
}
и она меняет в своем теле исходный аргумент.
Когда же аргумент не указывается, или когда указывается rvalue
, то есть некоторый временный объект, как, например,
func(); // используется аргумент по умолчанию int(), который равен 0
или
func( 10 ); // используется временный объект - целочисленный литерал - 10
то используется вторая функция
void func( int &&i = int() )
{
++i;
std::cout << "Insde func( int && ) i = " << i << std::endl;
}
Если же вы не собираетесь изменять исходный аргумент, то достаточно объявить одну функцию с параметром в виду константной ссылки. Например,
void func( const int &i = int() );
Ну, первый случай несложен - если вы хотите иметь возможность использовать значение по умолчанию, то используйте const int&
-
void f(const int& i = 5)
{
cout << i << endl;
}
Без const
, как вы понимаете, вам не удастся передать значение - ведь что тогда вы собираетесь менять, передавая число? :)
А вот так - можно:
int j = 5;
void f(int& i = j)
{
cout << i << endl;
}
int main(int argc, const char * argv[])
{
int q = 4;
f();
f(q);
}
Соответственно, то же и с set<int>&
- как вы себе представляете
для s вызывался конструктор, чтобы использовать множество set в теле функции
Т.е. вы хотите создавать новый set<int>
? Тогда где он должен быть создан? Как локальная переменная, как глобальная, как переменная в вызывающей функции?
Так что по умолчанию для ссылки надо указывать имеющийся объект. Другое просто не имеет никакого смысла. В конце концов, ссылка - это просто адрес, ждя которого гарантируется наличие корректного объекта.
"По-моему, так" (с) Пух
Если вам нужна именно неконстантная ссылка, то сделать в такой ситуации можно что-то вроде
void func2(set<int> &s = some_function())
где some_function
это
set<int> &some_function()
{
...
}
некая функция, которая отвечает за создание этих экземпляров std::set
в некоем хранилище. Отдельно придется подумать об обеспечении некоей политики их последующего уничтожения, когда они станут ненужными. Как это будет делаться - вопрос отдельный и элегантных решений тут навскидку не видно.
Оптимальное решение может зависеть от конкретной специфики вашей задачи, но сама идея неявного создания (потенциально долгоживущих) объектов через параметр по-умолчанию - сомнительна.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Столкнулся с очень необычной проблемойПричем что интересно, происходит она только в одном случае, когда происходит отладка юнит тестов (если...