【问题标题】:What's the best way to return a tuple from function in C++11?从 C++11 中的函数返回元组的最佳方法是什么?
【发布时间】:2013-05-18 18:32:37
【问题描述】:

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

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);
}

这些函数是等价的吗? 这些功能你更喜欢哪一个?

【问题讨论】:

  • 你在转发那些东西吗?不?使用std::make_tuple
  • 好吧,也不错。但是女巫与 make_tuple 和 forward_as_tuple 有真正的区别吗?
  • @GianLorenzoMeocci:forward_as_tuple 用于当您想要转发通用引用但作为元组时。如果您不知道这意味着什么,请不要使用它。

标签: c++ c++11 stdtuple


【解决方案1】:

std::forward_as_tuple() 创建一个 references 的元组。由于您无论如何都返回了tuple&lt;bool, string, int&gt;,因此两者最终是等效的在这种情况下,但我认为第一种方法更清晰 - 当您不转发任何内容时使用forward_as_tuple() 会令人困惑。

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

【讨论】:

  • 另外,效率更高。第一种方法可能使用复制省略(如果您将字符串文字包装在 std::string 构造函数调用中),第二种方法不能,因为它不是普通副本。
  • @SebastianRedl:正确,值得一提。谢谢
【解决方案2】:

我更喜欢,

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

编辑 1

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

我不知道 clang/libc++ 通过的原因,我想它是 libc++ 中的一个错误。无论如何,对于元组无法做到这一点很遗憾......

我想我意识到(对我来说,终于)它是多么可悲,一般来说。我已经习惯了这种语法,但人们不得不事先知道返回类型是否包含显式构造函数以便它随时工作。

编辑 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
}

【讨论】:

  • 我也更喜欢它,但std::tuple 有一个显式构造函数,这意味着上面不会编译
  • @AndyProwl 希望有人能将N3452 引入未来的标准。
  • @Morwenn:不知道,谢谢。但实际上,使tuple 的构造函数不显式还不够吗?我不明白为什么必须这样。毕竟pair的构造函数是不显式的
  • @AndyProwl,你知道为什么这会在 clang -std=c++11 下编译吗?
  • @Andy 不酷。这意味着如果我想要可移植代码,我使用 clang+libc++ 作为我的主要编译器很容易让人讨厌:( 我希望编译器/库编写者齐心协力,并让所有这些扩展都选择加入。这已经够糟糕了,我需要传递标志让编译器进入“真正的 C++”模式。如果这样做也没有给我想要的结果,那就更糟了。
猜你喜欢
  • 2013-10-31
  • 2010-09-07
  • 2013-03-30
  • 2010-10-16
  • 1970-01-01
  • 2014-02-13
  • 2013-08-12
  • 2012-10-23
相关资源
最近更新 更多