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

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

5 ответов

Решение

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

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

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

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

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

std::shared_ptr<void>

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

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

Ссылка: почему shared_ptr допустим, а unique_ptr не сформирован?

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

Другие вопросы по тегам