Исторически сложилось, что функция возвращает одно значение. В return.
Да, разумеется я знаю по ссылочные аргументы, про in/out аргументы и прочее изменение входных параметров. Но! Return все равно один.
То есть если рассматривать функцию как черный ящик, то выход у этого ящика всегда один.
Почему не придумали типа такого?
int/string/int* MyFunc()
{
int res1 = 5;
string res2 = “ssssss”;
int* res3 = (int*)malloc…;
return1 res1;
return2 res2;
return3 res3;
}
Print(MyFunc()2);
int b = MyFunc()1 + 6;
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Наверное потому что синтаксически громоздко, и тривиально решается кортежами, а ещё лучше полноценными структурами с именованными полями.
Нет. Я например сейчас разбираюсь в одной визуально программируемой штуке на нодах графа. Так вот там бывает, что у ноды три выхода, а у следующей ноды три входа. И они прям один к другому коннектятся. Хотя можно каждый выход и по отдельности использовать. То есть в коде это выглядело бы просто вызов одной функции как аргумент другой. Одна строчка. А вот с обычным подходом надо кучу кода городить
Здравствуйте, Буравчик, Вы писали:
Б>Здравствуйте, Hоmunculus, Вы писали:
H>>Почему не придумали типа такого?
Б>Придумали. Называется корутины. См. ключевое слово yield в разных языках программирования
Я знаю про них. Нет. Не то. Прочитай мой пример выше.
Здравствуйте, Буравчик, Вы писали:
Б>Здравствуйте, Hоmunculus, Вы писали:
H>>Я знаю про них. Нет. Не то. Прочитай мой пример выше.
Б>Прочитал, не вижу разницы. Поясни
У нас есть тяжелая функция. Вызывать ее несколько раз — накладно. Она должна за один проход вычислить кучу всего и отдать сразу же при вызове.
Да, и про классы я знаю. Городить класс вокруг каждой тяжелой функции — тоже не то
Здравствуйте, Hоmunculus, Вы писали:
H>У нас есть тяжелая функция. Вызывать ее несколько раз — накладно. Она должна за один проход вычислить кучу всего и отдать сразу же при вызове. H>Да, и про классы я знаю. Городить класс вокруг каждой тяжелой функции — тоже не то
Здравствуйте, Hоmunculus, Вы писали:
H>Здравствуйте, T4r4sB, Вы писали:
H>А, ну да. В Питоне вроде видел такое. Это питоновский кортеж?
Так-то это код на Русте.
На С++ это не сильно сложнее кстати
std::tuple<int,string,int*> MyFunc()
{
int res1 = 5;
string res2 = “ssssss”;
int* res3 = (int*)malloc…;
return {res1,res2,res3};
}
...
auto tuple = MyFunc(); // так можноauto [some_it, some_string, some_pointer] = MyFunc(); // так тоже можно начиная с ++17
Здравствуйте, Hоmunculus, Вы писали:
H>Почему не придумали типа такого?
int/string/int* MyFunc()
{
int res1 = 5;
string res2 = “ssssss”;
int* res3 = (int*)malloc…;
return1 res1;
return2 res2;
return3 res3;
}
Print(MyFunc()2);
int b = MyFunc()1 + 6;
Я тоже над этим думал, но вероятно нужно читать историю создания языка, причём языка Си откуда и пошёл C++. А в Си ещё так же нет функционального блока в отличие от Structured Text.
Я сейчас не говорю про лишнее копирование, то есть возврат по значению, а не по ссылке или ещё что-то такое. Но даже пользователи Си могут имитировать возврат множества аргументов, функциональный блок и прочее, причём разными способами.
По крайне мере именованные возвращаемые значения выглядят более логично, к тому же происходит возврат всех аргументов в одном месте.
Но с другой стороны можно вернуть значения в параметрах функции, можно использовать структуру. И я не думаю, что пользователи Си над этим заморачиваются.
Если уж философствовать, то почему бы всегда не передавать аргументы в функцию в структуре. Тогда получится единый подход к передаче данных.
Здравствуйте, Hоmunculus, Вы писали:
H>Почему не придумали типа такого?
Значит не нужно было.
H>То есть если рассматривать функцию как черный ящик, то выход у этого ящика всегда один.
Выходов может быть много. Вы не функции смотрите, а классы например там не только выходов, но и входов может быть сколько угодно.
Здравствуйте, T4r4sB, Вы писали:
V>>Я сейчас не говорю про лишнее копирование, то есть возврат по значению, а не по ссылке или ещё что-то такое. TB>А разве это в скомпилированном коде будет отличаться от возврата по ссылке?
Меня Страуструп в его книге учил, что нельзя полагаться на особое предопределённое поведение компиляторов. Какая это реализация компилятора, какой версии, какие флаги оптимизации и тому подобное.
Потому про компилятор и что у него "под капотом" ничего не скажу. Я веду речь только про то, что программист явно указывает в коде. А указать он может передача это по значению, по ссылке или по указателю.