Outputting a Returned pair Without a Temporary

470 Views Asked by At

Let's say that I have a function: pair<int, int> foo() I want to directly output both elements of this without using a temporary.

Is there a way that I can output this, or maybe convert it into a string to output? Could I perhaps use tie to do this?

Here's what I'm trying to do with the temporary:

const auto temporary = foo();

cout << temporary.first << ' ' << temporary.second << endl;
3

There are 3 best solutions below

0
OrdoFlammae On BEST ANSWER

No. You can't write that function without using a non-temporary. If you really need to, you should probably change the structure of your code. Technically, you could also use a global variable (although I strongly do not recommend this). I don't think tie would work for what you want it for either.

0
Not a real meerkat On

You can create a small class that wraps the std::pair, and enable output streams to print it via operator<<:

template<typename PairT>
struct printable {
    const PairT& p;
    printable(const PairT& p)
        :    p{p}
    {}
};

template<typename CharT, typename PairT>
std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& out, const printable<PairT>& pair) {
    out << pair.p.first << ' ' << pair.p.second;
    return out;
}

Then you can use it like this:

auto foo() {
    return std::pair<int, int>(1, 2);
}

int main() {
    std::cout << printable(foo());
}

Live example


Of course, you could also just enable the printing directly for an std::pair...

template<typename CharT, typename A, typename B>
std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& out, const std::pair<A, B>& pair) {
    out << pair.first << ' ' << pair.second;
    return out;
}

// (...)

std::cout << foo(); // And this would work just fine

... but I don't really recommend it, specially on a header, since you would be basically changing behavior of standard types and your colleagues (or yourself, in the future) may be confused by it.

1
hare1039 On

In c++17 standard, you can use structured binding declaration

std::pair<int, int> get_pair()
{
    return {10, 20};
}

int main()
{
    auto [x, y] = get_pair();
    std::cout << x << " " << y << std::endl;
    return 0;
}