C++使用结构返回多个值

C++ Returning Multiple Values with a Struct

本文关键字:返回 结构 C++      更新时间:2023-10-16

我知道std::tuple是从函数返回多个不同类型的变量的有效方法,正如 Herb Sutter 在大约 1:31:00 的演讲中提到的(这个代码示例是我的,而不是来自视频)

auto get_tuple()
{
  return std::make_tuple(1, 2);
}

然后用其中之一"解包"它

auto t = get_tuple();
int a = std::get<0>(t);
int b = std::get<1>(t);

int a;
int b;
std::tie(a, b) = get_tuple();

这些方法很棒,但我不是特别喜欢语法std::getstd::tie。我不会仅仅因为丑陋的语法(在我个人看来)而避免使用有用的工具,但是这样做呢?

auto get_struct()
{
  struct R
  {
    int a;
    int b;
  }
  return R{1, 2};
}

这为我编译(Visual Studio 2015),我更喜欢它的语法。我不想被指责过早优化,但我还要提到它似乎比元组快很多倍。大多数情况下,我只是喜欢语法。

也就是说,我知道仅仅因为某些东西可以编译并不意味着该语言应该以这种方式使用。我不完全确定如何措辞这个问题,但基本上,这是有效且定义的行为吗?我可以确信这将适用于其他主要编译器吗?坦率地说,我很惊讶即使该类型是在函数本身中定义的,它也会推断出类型,所以我想确保这是可以的。

这是我第一次在这个网站上发帖,如果我做错了什么,提前道歉。如果我这样做了,请告诉我。

编辑:正如在回应中指出的那样,我声称本地结构比元组快很多倍是完全错误的。我没有正确地进行测试。查看回复以获取更多信息,我只是想对其进行编辑以确保我不会误导任何人。

虽然本地结构符合标准,但我建议不要使用它(而不是元组)。首先,性能度量可能不正确。

以下代码:

#include <tuple>
auto get_tuple()
{
  auto tup = std::make_tuple(1.0f, 2.0f);
  return tup;
}
auto get_struct() {
  struct R {
    float a, b;
  };
  return R{1, 2};
}

在优化模式下生成以下 ASM:

get_tuple():
        movq    %rdi, %rax
        movl    $0x40000000, (%rdi)
        movl    $0x3f800000, 4(%rdi)
        ret
get_struct():
        movq    .LC3(%rip), %xmm0
        ret
.LC3:
        .quad   4611686019492741120

所以它只长了两个movl指令。我认为不可能衡量这种影响。

元组提供的不仅仅是结构!你可以知道它的大小在元素方面(在编译时)。您可以合并元组。您可以在它们上构建反射系统。您可以将它们与 std::tie .您可以提供它们的类型。(使用本地结构,它将一直自动向下)。本地结构中没有类似的东西。

[...]这是有效和定义的行为吗?

是的,您可以声明一个本地类并返回它的实例。这完全没问题。

我不想被指责过早优化,但我还要提到它似乎比元组快很多倍。

我怀疑由两个intstd::tuple<int, int>组成的本地结构之间的运行时性能是否应该有任何不同。当然,编译时tuple会更慢。

因为一旦你返回了一个本地类的实例,它就不是真正的本地类,你可以把它变成一个非本地类:

struct R { ... };
R get_struct();

那么就更不用说这是否有效了。

此外,您始终可以直接将元组输出插入解压缩它的内容中。查看Yakk的答案,例如:

std::tuple<int, int> get_tuple();
unpack(get_tuple(), [](int i, int j) { ... });
get_tuple() *then* [](int i, int j){ ... };

您可能还很高兴知道有一个结构化绑定提案,它直接允许:

auto {a, b} = get_tuple();

这是有效的行为,您是正确的,它比使用元组更快。但是,您使用的是具有内置类型的简单案例。尽管语法不太优雅,但使用 std::tuple 和具有用户定义类型的struct的性能差异可能会使使用std::tuple更具吸引力。