ariya.io About Collections Archives

C++ Multiple Return Values

3 min read

ninja
With a complex application, it is often convenient to have a function that returns not just one value. There are many different ways to achieve this in C++, from using a structure to taking advantage of the latest C++ 11 tuple class template.

The obvious choice, returning an object, seems a bit overkill in many cases. First, you need to declare the structure. It is not seldom that the structure needs to be available for the consumer, hence you have to expose it to the outside world. The construction of the instance is also another ceremonial activity nobody likes to carry out unnecessarily.

Fortunately, if the function is supposed to return only two values, std::pair is to the rescue. Most likely, make_pair will be used to construct the pair. Each element of the pair can be accessed using first and second, respectively. This is illustrated in the following example:

std::pair<std::string , int> findPerson() {
    return std::make_pair("Joe Sixpack", 42);
}
 
int main(int, char**) {
    std::pair< std::string, int> person = findPerson();
    std::cout < < "Name: " << person.first << std::endl;
    std::cout << "Age: " << person.second << std::endl;
    return ;
}

What if you need more than just two values? Well, obviously std::pair is not fit for the job. In this case, we can leverage boost:tuple from Boost Tuple library. If you are already using std::pair, it is very easy to get familiar with boost::tuple. A tuple can be created using make_tuple, its element is accessed using get<n>, where n denotes the element index.

#include <boost /tuple/tuple.hpp>
 
boost::tuple<std::string , std::string, int> findPerson() {
    return boost::make_tuple("Joe", "Sixpack", 42);
}
 
int main(int, char**) {
    boost::tuple< std::string , std::string, int> person = findPerson();
    std::cout < < "Name: " << person.get< >() < < " "
        << person.get< 1>() < < std::endl;
    std::cout << "Age: " << person.get< 2>() < < std::endl;
    return ;
}

With the latest C++ 11, there is no need to rely on a third party library anymore since std::tuple is already available. With minor tweaks, the previous Boost example will look this in C++. Note also the use auto that saves us from unnecessary verbosity. The compiler knows the return type of findPerson and there is no need for a lengthy type declaration anymore.

#include <tuple>
 
std::tuple<std::string , std::string, int> findPerson() {
    return std::make_tuple("Joe", "Sixpack", 42);
}
 
int main(int, char**) {
    auto person = findPerson();
    std::cout < < "Name: " << std::get< >(person) < < " " <<
        std::get< 1>(person) < < std::endl;
    std::cout << "Age: " << std::get< 2>(person) < < std::endl;
    return ;
}

While we are at it, might as well mention std::tie, useful to easily unpack a tuple (similar to ES6 destructuring). It is convenient alternative to the element access using get. The code fragment below demonstrates its usage.

int main(int, char**) {
    std::string first_name, last_name;
    int age;
    std::tie(first_name, last_name, age) = findPerson();
    std::cout < < "Name: " << first_name << std::endl;
    return ;
}

From your own experience, which of these techniques do you like and why do you favor it?

Related posts:

♡ this article? Explore more, check the archives, or follow me Twitter.

Share this on Twitter Facebook Google+

comments powered by Disqus