tuple
в повышении и TR1/c ++ 0x предоставляет удобное (устройству записи функции) метод для возвращения двух значений от функции - однако это, кажется, повреждает одну основную функцию языка для вызывающей стороны: способность просто использовать функцию для инициализации переменной:
T happy();
const auto meaningful_name(happy()); // RVO means no excess copies
но для:
tuple<T,U> sad();
мы любой должен сдать способность выбрать понятное имя для наших возвращаемых значений и использование get<n>()
везде:
const auto two_unrelated_things(sad());
или сделайте временный файл:
const auto unwanted_named_temporary(sad());
const auto one_name(get<0>(unwanted_named_temporary));
const auto two_name(get<1>(unwanted_named_temporary));
или переключатель от инициализации до присвоения, которое только работает, когда типы являются присваиваемыми, и повреждения 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();
или сделайте что-то неестественное к локальному классу:
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
Существует ли лучший путь? Я использую совместимые конструкции VC10 выше, был бы что-нибудь в полном C++ 0x или справка повышения?
Идеально это было бы:
std::tuple<Type1, Type2> returnValue = sad();
Type1& first = std::get<0>(returnValue);
Type2& second = std::get<1>(returnValue);
Я не уверен, что означает ваша четвертая пуля, но всех остальных это устраивает.
* edit: Основываясь на вашем комментарии выше, я понял, что вы имели в виду под четвертым маркером.
struct Object {
Object(const std::tuple<Type1, Type2>& t) : value(t) { }
Type1& First() { return std::get<0>(value); }
Type2& second() { return std::get<1>(value); }
private:
std::tuple<Type1, Type2> value;
}
При необходимости измените.
Вы также можете вообще не использовать std :: tuple
, если возвращаемые значения настолько не связаны, что вам придется разделить их, чтобы их можно было использовать разумно. Люди годами возвращали struct
s с полями с разумными именами или путем принятия ссылочных параметров для вывода.
Кстати, вы, кажется, влюблены в auto
. Не надо. Это отличная функция, но это не способ ее использования. Ваш код будет неразборчивым, если вы время от времени не будете указывать типы.