Он подумал, что было бы интересно вернуть несколько значений (с разными типами!) Из вызова функции C ++.
Поэтому я посмотрел вокруг, чтобы найти какой-то пример кода, но, к сожалению, не смог найти ничего подходящего для этой темы.
Я хотел бы функцию, как …
int myCoolFunction(int myParam1) {
return 93923;
}
работать с различными типами, чтобы вернуть несколько различных типов значений, таких как
?whatever? myCoolFunction(int myParam1) {
return { 5, "nice weather", 5.5, myCoolMat }
}
Так что-то подобное возможно с использованием C ++
(Моя идея состояла в том, чтобы использовать специальный AnyType-вектор, но я не мог найти пример кода поэтому) или я должен оставаться на этом типе вызова? (увидеть ниже)
void myCoolFunction(cv::Mat &myMat, string &str){
// change myMat
// change str
}
Заметка: Таким образом, порядок и количество возвращаемых элементов будут одинаковыми каждый раз -> Набор остается идентичным (например, 1.:double, 2.:int
в каждом случае)
Если вы хотите вернуть несколько значений, вы можете вернуть экземпляр класса, заключающий в себе разные значения.
Если вы не заботитесь о потере семантики, вы можете вернуть std::tuple
1:
auto myCoolFunction(int myParam1) {
return std::make_tuple(5, "nice weather", 5.5, myCoolMat);
}
Если вы хотите форсировать типы (например, иметь std::string
вместо const char *
):
std::tuple<int, std::string, double, cv::Mat> myCoolFunction(int myParam1) {
return {5, "nice weather", 5.5, myCoolMat};
}
В обоих случаях вы можете получить доступ к значениям, используя std::get
:
auto tup = myCoolFunction(3);
std::get<0>(tup); // return the first value
std::get<1>(tup); // return "nice weather"
1 Если у вас есть компилятор, совместимый с C ++ 17, вы можете использовать вычет аргумента шаблона и просто вернуть std::tuple{5, "nice weather", 5.5, myCoolMat}
,
Вы можете вернуть структуру или использовать std :: tuple.
Используя struct, вы можете сделать:
myStruct create_a_struct() {
return {20, std::string("baz"), 1.2f};
}
И с std :: tuple
std::tuple<int, std::string, float> create_a_tuple() {
return {20, std::string("baz"), 1.2f};
}
Конечно, это возможно, используя std::tuple
, доступно в стандартной библиотеке начиная с C ++ 11:
#include <tuple>
std::tuple<int, std::string, double, cv::Mat>
myCoolFunction(int myParam1) {
return { 5, "nice weather", 5.5, myCoolMat }
}
Если вам разрешено использовать код C ++ 14, вам даже не нужно объявлять тип:
#include <tuple>
auto myCoolFunction(int myParam1) {
return std::make_tuple(5, "nice weather", 5.5, myCoolMat);
}
а также вот доказательство того, что обе эти версии компилируются (без cv::Mat
— Я не думаю, что GodBolt это доступно).
Заметки:
std::make_tuple
типы могут не соответствовать вашим ожиданиям. Например, в этом случае вы получите char *
хотя при явном определении кортежа его можно заставить std::string
как у меня выше. Обычно это не проблема.std::move
это, чтобы избежать копирования всей вещи, например, прохождение std::move(myCoolMat)
,(Ответьте за забаву действительно и продемонстрируйте силу C ++, а не что-нибудь еще.)
Одним из способов, который на самом деле является довольно злым, так как вы обременяете сайт звонков распаковкой контента, является использование
std::shared_ptr<void>
как тип возвращаемого значения. Это разрешено с std::shared_ptr
опоры стирание типа. (К несчастью, std::unique_ptr
не так, вы должны исключить это.)
Очевидно, что в функции вам нужно будет использовать std::make_shared
или похожие.
Ссылка: Почему shared_ptr<недействительным> законно, а unique_ptr<недействительным> плохо сформирован?
Возвращает std :: vector из std :: option, где std :: variable является параметризованным шаблоном для вашего выбора типов. Если какой-либо тип действительно возможен, я не уверен, почему вы делаете это со структурами, а не просто записываете в область памяти; Отсутствие детерминированной концепции объектов и типов в структуре имеет низкую ценность.