C++: Return multiple values of different types from a function

Akshay Chavan
3 min readAug 27, 2020
Photo by Markus Spiske on Unsplash

Having done a lot of programming in C++0x and then spending a lot of time on Python programming. I got used to a lot of features in Python and remembered how tedious it is to get the things done in C++. Mind you C++ is definitely faster of the two.

One of the Python features I like the most, is the ability to return multiple values of different types from a function. In Python, when you return multiple values of different types from a function you are actually returning a tuple.

I was happy to find out that since C++11 there is support for a fixed-size collection of heterogeneous values called tuple. The characteristics of a tuple is very similar in Python and C++.

To use a tuple in C++ you have to include the header #include <tuple>.

Here is an example of a function that returns a tuple.

#include <iostream>
#include <tuple>
#include <string>

std::tuple<int, bool, std::string> returnTuple() {
return std::tuple<int, bool, std::string>{100, true, "Error Message"};
}

int main() {
std::tuple<int, bool, std::string> t = returnTuple();
std::cout << "int=" << std::get<0>(t) << std::endl;
std::cout << "bool=" << std::get<1>(t) << std::endl;
std::cout << "string=" << std::get<2>(t) << std::endl;
}
// Output
// int=100
// bool=1
// string=Error Message

A shorter way to make a tuple is by using std::make_tuple, where you don't have to specify the data types. However, in this case they need to match the return type.

std::tuple<int, bool, std::string> returnTuple() {
return std::make_tuple(100, true, "Error Message");
}

The compiler tries to convert the values to a data type that matches the return type.

std::tuple<int, bool, std::string> returnTuple() {
return std::make_tuple(100.0, 5, "Error Message");
}
// Output
// int=100 Fraction gets converted to whole number
// bool=1 Anything not equal to zero gets converted to one or true
// string=Error Message

And if the value cannot be implicitly converted they you get a conversion error during compilation.

std::tuple<int, bool, std::string> returnTuple() {
return std::make_tuple(100.0, 5, 'c');
// Compilation error: no viable conversion
}

To access an element in tuple by index you make use of std::get.

int main() {
std::tuple<int, bool, std::string> t = returnTuple();
std::cout << "int=" << std::get<0>(t) << std::endl;
std::cout << "bool=" << std::get<1>(t) << std::endl;
std::cout << "string=" << std::get<2>(t) << std::endl;
}

Now, if you already have variables defined in which you want to capture the values from a function that returns a tuple. You need to use std::tie.

int main() {
int i;
bool b;
std::string str;
std::tie(i, b, str) = returnTuple();
}

If you want to ignore some elements of the returned tuple, then literally use std::ignore.

int main() {
int i;
bool b;
std::tie(i, b, std::ignore) = returnTuple();
}

One last thing, to concatenate tuples you can use std::tuple_cat.

std::tuple<int, bool, std::string> t1(100, true, "Error Message");
auto bigtuple = std::tuple_cat(t1, std::make_tuple("Foo", "bar"));
std::cout << "bigtuple[3] = " << std::get<3>(bigtuple) << std::endl;
// Output
// bigtuple = Foo

--

--