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

How to initialize with multiple return values in c++(0x)

boost和TR1 / c 0x中的

tuple提供了一种方便的方法(对于函数的编写者),该方法可以从函数中返回两个值-然而,这似乎损害了调用者语言的一个主要功能:只需使用函数即可初始化变量的能力:

1
2
T happy();
const auto meaningful_name(happy()); // RVO means no excess copies

但适用于:

1
tuple<T,U> sad();

我们要么不得不放弃为返回值选择一个有意义的名称的能力,要么在任何地方都使用get<n>()

1
const auto two_unrelated_things(sad());

或临时设置:

1
2
3
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

1
2
3
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();

或对本地类做一些不自然的事情:

1
2
3
4
5
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
2
3
std::tuple<Type1, Type2> returnValue = sad();
Type1& first = std::get<0>(returnValue);
Type2& second = std::get<1>(returnValue);

我不确定您的第四个项目符号是什么意思,但这足以满足其余所有要求。

* edit:根据您上面的评论,我弄清楚了您所说的第四个项目符号是什么意思。

1
2
3
4
5
6
7
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。别这样这是一个很大的功能,但这不是应使用的方式。如果您不时指定类型,您的代码将最终变得难以辨认。