Может ли функция возвращать несколько значений разных типов?

Он подумал, что было бы интересно вернуть несколько значений (с разными типами!) Из вызова функции 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 в каждом случае)

2

Решение

Если вы хотите вернуть несколько значений, вы можете вернуть экземпляр класса, заключающий в себе разные значения.

Если вы не заботитесь о потере семантики, вы можете вернуть std::tuple1:

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},

4

Другие решения

Вы можете вернуть структуру или использовать 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};
}
2

Конечно, это возможно, используя 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),
2

(Ответьте за забаву действительно и продемонстрируйте силу C ++, а не что-нибудь еще.)

Одним из способов, который на самом деле является довольно злым, так как вы обременяете сайт звонков распаковкой контента, является использование

std::shared_ptr<void>

как тип возвращаемого значения. Это разрешено с std::shared_ptr опоры стирание типа. (К несчастью, std::unique_ptr не так, вы должны исключить это.)

Очевидно, что в функции вам нужно будет использовать std::make_shared или похожие.

Ссылка: Почему shared_ptr<недействительным> законно, а unique_ptr<недействительным> плохо сформирован?

0

Возвращает std :: vector из std :: option, где std :: variable является параметризованным шаблоном для вашего выбора типов. Если какой-либо тип действительно возможен, я не уверен, почему вы делаете это со структурами, а не просто записываете в область памяти; Отсутствие детерминированной концепции объектов и типов в структуре имеет низкую ценность.

-4
По вопросам рекламы [email protected]