I'm writing a small library which has some API function returning two things (of different types). I'd rather not declare a struct just for that; so I'm thinking of returning an std::pair<foo, bat>
. But - perhaps in these modern times I should prefer returning std::tuple<foo, bar>
instead?
More generally, when should a tuple be prefered over a pair, and when is pair the more appropriate construct?
You should declare a struct for that.
get<0>(x)
andget<1>(x)
, or even post-C++11'sget<Foo>(x)
andget<Bar>(x)
, are less meaningful and/or idiomatic thanx.foo
orx.bar
.tuple
s are best for non-uniformly typed things that are identified by order.pair
s are atuple
that was written prior to C++11.Both
pair
andtuple
(andarray
while we are at it) are tuple-like, in that they supportstd::tuple_size
andget<N>
.It has been considered an error in the
std
library that so many types usepair
instead of structures with properly named fields. Ie, ifmap
usedstruct KV{ Key key; Value value; }
, it would have been better.Now, metaprogramming support for
KV
as a generic pair would be good as well. So,tuple_size
andget<0>
etc. But throwing away named fields is generally a bad idea. Names have power.With C++17, simple
struct
s start working with structured binding, even if you don't make them "tuple-like".If you do have things whose identity is determined by their order of non-uniform type,
tuple
is the way to go.pair
is a nearly legacy type. There are some advantages topair
overtuple
, buttuple
continues to be improved to remove them (like implicit initialization oftuple
).