如何使用c ++(0x)中的多个返回值进行初始化

时间:2010-08-07 08:05:41

标签: c++ boost c++11 tuples

boost中的

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或boost帮助?

理想情况下会:

  • 允许我使用初始化,而不仅仅是分配
  • 调用者选择返回变量的名称
  • 不要制作额外的副本
  • 适用于堆栈变量和类成员
  • 可能是一个很大的疯狂模板库,但对于调用者和函数编写者来说,它具有理智的语法

1 个答案:

答案 0 :(得分:2)

std::tuple<Type1, Type2> returnValue = sad();
Type1& first = std::get<0>(returnValue);
Type2& second = std::get<1>(returnValue);

我不确定你的第四颗子弹是什么意思,但这完全满足了所有其他。

*编辑:根据您上面的评论,我想出了第四个项目符号的含义。

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,或者接受输出的参考参数。

顺便说一句,你似乎爱上了auto。不要。它是一个很棒的功能,但它它应该被使用的方式。如果您不经常指定类型,您的代码将最终难以辨认。