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.fooorx.bar.tuples are best for non-uniformly typed things that are identified by order.pairs are atuplethat was written prior to C++11.Both
pairandtuple(andarraywhile we are at it) are tuple-like, in that they supportstd::tuple_sizeandget<N>.It has been considered an error in the
stdlibrary that so many types usepairinstead of structures with properly named fields. Ie, ifmapusedstruct KV{ Key key; Value value; }, it would have been better.Now, metaprogramming support for
KVas a generic pair would be good as well. So,tuple_sizeandget<0>etc. But throwing away named fields is generally a bad idea. Names have power.With C++17, simple
structs 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,
tupleis the way to go.pairis a nearly legacy type. There are some advantages topairovertuple, buttuplecontinues to be improved to remove them (like implicit initialization oftuple).