tuple
in boost and TR1/c++0x provides a convenient (for the writer of the function) method to return two values from a function--however it seems to damage one major feature of the language for the caller: the ability to simply use the function to initialize a variable:
T happy();
const auto meaningful_name(happy()); // RVO means no excess copies
but for:
tuple<T,U> sad();
we either have to surrender the ability to pick a meaningful name for our return values, and use get<n>()
everywhere:
const auto two_unrelated_things(sad());
or make a temporary:
const auto unwanted_named_temporary(sad());
const auto one_name(get<0>(unwanted_named_temporary));
const auto two_name(get<1>(unwanted_named_temporary));
or switch from initialization to assignment, which only works when the types are assignable, and breaks auto
:
tuple_element<0, decltype(sad())>::type one_mutable; // there might be a less
tuple_element<1, decltype(sad())>::type two_mutable; // verbose way
tie(one_mutable,two_mutable) = sad();
or do something unnatural to a local class:
const struct ugh {
ugh( decltype(sad()) rhs ) : one_name(get<0>(rhs)), two_name(get<1>(rhs)) {}
const tuple_element<0, decltype(sad())>::type one_name;
const tuple_element<1, decltype(sad())>::type two_name;
} stuff(sad()); // at least we avoid the temporary and get initialization
Is there a better way? I'm using VC10 compatible constructs above, would anything in full c++0x or boost help?
Ideally it would:
- allow me to use initialization, not just assignment
- let the caller pick the names for the returned-into variables
- not make extra copies
- work for both stack variables and class members
- possibly be a big crazy template library, but have sane syntax for caller and function writer