Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
1

Опциональный ссылочный аргумент функции

23.02.2014, 09:46. Показов 4027. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Некоторые аргументы функции можно сделать опциональными, просто поставив значение по умолчанию, а затем проверяя, изменилось ли оно :
C++
1
2
3
4
5
6
7
void someFoo(int important, int *additional = NULL)
{
if (additional != NULL)
{
//do someFoo
}
}
Можно ли сделать так же для ссылочного типа?
C++
1
2
3
4
5
6
7
void someFoo(int important, int &additional) // ???
{
if (additional) //  ??? -> PROFIT
{
//do someFoo
}
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2014, 09:46
Ответы с готовыми решениями:

Опциональный вызов деструктора в шаблоне
Разбираясь с шаблонами, решил описать набор шаблонов для работы с матрицами. Выделение памяти,...

Вычислить значение функции аргумент которой вычисляется из другой кусочно заданной функции
Решите программу то я не знаю как:hysteric: Вычислить значение y в зависимости от выбранной...

Передача функции в аргумент
Есть три функции: void MainMenu(); void MainMenu_MilkMenu(); bool ErrorMenu(void (*pf)()); ...

Беззнаковый аргумент функции
Всем привет. Есть вопрос по уточнению типа аргументов функций. К примеру, есть функция:...

24
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
23.02.2014, 09:47 2
Нет, ссылка должна быть инициализирована и не имеет null-семантики (простите за варварские формулировки)
1
2848 / 1997 / 986
Регистрация: 21.12.2010
Сообщений: 3,705
Записей в блоге: 10
23.02.2014, 10:27 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
void Func(int const& num = 0)
{
    int& num1 = const_cast<int&>(num);
    num1 = 120;
    std::cout << "Func: " << num << '\n';
}
 
 int main ()
 {
     int num = 390;
     Func(num);
     std::cout << num << '\n';
     return 0;
 }
2
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
23.02.2014, 11:56 4
igorrr37, всё-таки речь шла о неконстантной ссылке. Тем более, если в 12 строке будет:
C++
1
const int num
, то получите UB из-за const_cast.
Если нужно просто сделать ссылочное значение по умолчанию, достаточно такого:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
int i = 42;
 
void Func(int& num = i)
{
    std::cout << "Func: " << num << '\n';
}
 
int main()
{
    int num = 390;
    Func(num);
    Func();
    return 0;
}
http://ideone.com/qjbjEj
Но, как уже сказал 0x10 ссылка должна быть инициализирована, т.е. указывать на объект.

А если хочется сделать код максимально похожий на код ТС, то можно предложить такой вариант:
C++
1
2
3
4
5
6
7
8
int i = 0;
void someFoo(int important, int &additional = i) 
{
    if (additional) 
    {
        
    }
}
Однако, здесь не стоит путать нулевое значение целого аргумента и отсутствие значения (как можно было бы интерпретировать с nullptr).
2
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
24.02.2014, 18:44  [ТС] 5
Tulosba, безопасно ли делать нечто подобное?
C++
1
2
3
4
5
6
7
8
9
10
11
12
string Foo(string & str = string())
{
//something to exit
Foo(str);
//something to calc
return str;
}
 
int main()
{
Foo();
}
Вроде как должно же быть? По сути, объект создатся локально один раз, будет отправлен по ссылке в рекурсию, после чего вернется в свою проматерь, где создастся его копия, которая вернется в return, а сам он помрет?

Добавлено через 6 минут
Если это нормально, то, выходит, впорядке будет и такое:
C++
1
2
3
4
void Foo(double & x = double(0))
{
//те же условия
}
? Точнее, должно быть впорядке, однако создать подобным образом аргумент примитивного типа не выйдет, а создавать глобавльную переменную - не выход.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
24.02.2014, 20:14 6
nexen, во-первых, рекурсия бесконечная. Во-вторых, чтобы это собиралось, надо хотя бы ссылку сделать константной. Ну и с double отличий тогда не будет никаких от варианта со string.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
24.02.2014, 20:27  [ТС] 7
Tulosba, в рекурсии я в комментах написал, что есть условие на выход.
Без константной ссылки собирается. Проверено.
А double(0) не собирается для неконстантной ссылки, так что тут другое. А хотелось бы, чтобы собиралось
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
24.02.2014, 20:36 8
Цитата Сообщение от Tulosba Посмотреть сообщение
Во-вторых, чтобы это собиралось, надо хотя бы ссылку сделать константной
Это так в соответствии со стандартом (нельзя привязывать не константную ссылку к rvalue), однако студия 2010 и ниже нарушала это правило и позволяла эту конструкцию (как расширение языка).

Добавлено через 19 секунд
Цитата Сообщение от nexen Посмотреть сообщение
Без константной ссылки собирается. Проверено.
См. мой ответ
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
24.02.2014, 20:53 9
Цитата Сообщение от DrOffset Посмотреть сообщение
однако студия 2010 и ниже
судя по всему и 2012 допускает.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
24.02.2014, 20:55  [ТС] 10
Tulosba, DrOffset, но что же тогда делать? Хочется ведь не передавать лишних параметров в функцию, а сделать для рекурсии локальную карту (std::map) для некоторых внутренних нужд, которая должна быть доступна из любого уровня рексии. 2008 студия позволила сделать то, что я описывал выше, благодоря чему такой финт с map работал, но с const map<>& такое не сработает, ибо константа..
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
24.02.2014, 20:59 11
Цитата Сообщение от nexen Посмотреть сообщение
для некоторых внутренних нужд, которая должна быть доступна из любого уровня рексии.
Так может быть это должно быть полем класса?
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
24.02.2014, 21:02 12
Цитата Сообщение от Tulosba Посмотреть сообщение
судя по всему и 2012 допускает.
Да. Однако странная разница в поведении, когда меняется тип с встроенного на не встроенный.

Добавлено через 2 минуты
Цитата Сообщение от nexen Посмотреть сообщение
но что же тогда делать?
В С++11 есть rvalue references.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
25.02.2014, 15:00  [ТС] 13
DrOffset, можете пример с r-ref показать?
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
25.02.2014, 15:09 14
Цитата Сообщение от nexen Посмотреть сообщение
можете пример с r-ref показать?
C++
1
2
3
4
string Foo(string && str = string())
{
    return str;
}
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
25.02.2014, 16:24  [ТС] 15
DrOffset, а она разве в случае, когда нужно сделать рекурсию с внутренними данными поможет?
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
25.02.2014, 16:30 16
Цитата Сообщение от nexen Посмотреть сообщение
а она разве в случае, когда нужно сделать рекурсию с внутренними данными поможет?
Честно говоря не очень понята эта формулировка.
Но смысл она (rvalue reference) несет тот же, что и в записи с неконстантной ссылкой. Временный объект не копируется, привязывается к ссылке с именем str.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
25.02.2014, 17:07  [ТС] 17
DrOffset, я про то, что писал выше:
C++
1
2
3
4
5
6
7
8
9
10
11
12
string Foo(string & str = string())
{
//something to exit
Foo(str);
//something to calc
return str;
}
 
int main()
{
Foo();
}
Мне изначально это нужно было, чтобы вызывать функцию без аргументов да так, чтобы внутри неё формировался некоторый массив ответов (в примере это строка), а затем уже возвращалась копия того локального массива, который создавался в функции (конечно, жаль, что копия, а не сам объект, но что поделать). Разве в этом случае && мне поможет?
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
25.02.2014, 19:05 18
Цитата Сообщение от nexen Посмотреть сообщение
Разве в этом случае && мне поможет?
За исключением того, что в твоем примере изначально бесконечная рекурсия, не вижу причин почему нет?
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
25.02.2014, 20:42  [ТС] 19
DrOffset, как я уже отвечал выше, я же в комментариях написал, что есть нечто, для выхода из функции "//something to exit" - 3 строка.
То есть && может выполнять ту же функцию, что и &?
0
18893 / 9850 / 2410
Регистрация: 30.01.2014
Сообщений: 17,293
25.02.2014, 21:04 20
Цитата Сообщение от nexen Посмотреть сообщение
DrOffset, как я уже отвечал выше, я же в комментариях написал, что есть нечто, для выхода из функции "//something to exit" - 3 строка.
То есть && может выполнять ту же функцию, что и &?
Может быть стоит попробовать, а потом задать вопросы, если не получится?
0
25.02.2014, 21:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.02.2014, 21:04
Помогаю со студенческими работами здесь

Не читается аргумент функции
void recursReverse(char* str, size_t len) { static size_t len2 = len; while (len2 &gt; 1) ...

Непонятный аргумент функции
Кто-нибудь может подсказать, что принимает такая функция в качестве аргумента? void foo(int...

Безымянный аргумент функции
функция принимает аргумент, но у него нет имени void f(int) { cout &lt;&lt; &quot;Hello world!&quot;; } ...

Аргумент argv в функции main()
Здравствуйте. Возникли некоторые непонимания при работе с аргументом argv и указателями в целом. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru