在C ++ 11中从函数返回元组的最佳方法是什么?

时间:2013-05-23 11:54:26

标签: c++ c++11 stdtuple

我想从函数返回一些值,我想将它打包成一个元组。所以我有两种函数声明的可能性:

std::tuple<bool, string, int> f()
{
  ...
  return std::make_tuple(false, "home", 0);
}

std::tuple<bool, string, int> f()
{
  ...
  return std::forward_as_tuple(false, "home", 0);
}

这些功能是等价的吗? 在您喜欢的这些功能之间?

2 个答案:

答案 0 :(得分:21)

std::forward_as_tuple()创建引用元组。既然你要返回一个tuple<bool, string, int>,那么这两个最终在这种情况下等同于 ,但我认为第一种方法更清楚 - 当你不转发任何东西时使用forward_as_tuple()令人困惑。

另外,正如Sebastian Redl在评论中所提到的,make_tuple()将允许编译器执行复制省略 - 根据C ++ 11标准的第12.8 / 31段,而forward_tuple()则不会(因为它返回的内容与函数的返回类型的类型不同。

答案 1 :(得分:5)

我更喜欢,

std::tuple<bool, std::string, int> f()
{
  ...
  return { false, "home", 0 };
}

编辑1

上面的代码实际上是在clang / libc ++ trunk下编译的。正如@AndyProwl在注释部分中评论的那样,这不应该是因为std :: tuple构造函数是显式的,并且通过initial-list语法返回是在复制初始化上下文中,因此复制列表初始化,当匹配显式构造函数时失败。

我不知道clang / libc ++传递的原因,我想它是libc ++中的一个bug。无论如何,对于元组来说,这是不可能的......

我认为我总体上意识到这对我来说是多么悲伤(对我而言)。我已经习惯了这种语法,但是人们必须事先知道返回类型是否随时都包含一个显式构造函数。

编辑2

这确实是一个libc ++扩展,有关更多信息,请查看Howard Hinnant在这里回答:https://stackoverflow.com/a/14963014

它目前也在libc ++错误列表中打开:http://llvm.org/bugs/show_bug.cgi?id=15299

这是相关提案:Daniel Krügler, Improving pair and tuple

简而言之,这就是libc ++:

#include <tuple>
#include <string>

struct S
{
    explicit S(int) {}
};

int main()
{
    std::tuple<int, std::string> t1 = { 1, "hello" }; // ok
    std::tuple<std::string> t2      = "hello";        // ok
    std::tuple<int, S> t3           = { 1, 1 };       // fail: an *element* is to be constructed explicitly
}