结构化绑定和强制拷贝省略

3
如果您使用结构化绑定,就像这样:
auto [a, b, c] = std::make_tuple(1, 10.0, "string object"s);

那么,从返回的元组中复制的副本将被省略并且对象直接进入abc中,还是初始化将从各个元组元素进行移动构造?我怀疑这不会导致复制发生,但我不确定标准中强制复制省略的描述是否处理了这种情况。

返回的元组副本会被省略,对象直接进入a、b和c吗?不会。初始化将是从各个元组元素进行移动构造吗?也不会。 - cpplearner
@cpplearner 那么它们被复制了吗? - Curious
1个回答

4

正如这篇优秀的答案所介绍的那样,声明等同于:

auto e = std::make_tuple(1, 10.0, "string object"s);
int& a = get<0>(e);
double& b = get<1>(e);
std::string& c = get<2>(e);

除了没有一个名字叫做e之外,get函数在这个上下文中产生了一个所选项目的左值引用。在C++17中,auto name = prvalue; 被定义为声明一个名为name的对象,类型为decltype(prvalue),用prvalue表达式初始化——与以前的版本不同,没有可消除的中间临时变量。换句话说,e声明的行为与以下内容完全相同:
std::tuple<int, double, std::string> e {1, 10.0, "string object"s};

然后a、b、c是对该元组中元素的引用。


注意:以上解释对应最新的C++17草案源代码;当然,在C++17最终确定之前,行为可能会发生改变。

在这个例子中,abc&&,并且在相当于 std::move(e) 的对象上调用了 get - T.C.
1
这里的措辞相当棘手。关键句子是:“在任何情况下,如果实体e的类型是左值引用,则e是一个左值;否则e是一个x值。” - T.C.
没错,这不完全是在/1中引入的变量e。本质上,这是核心语言风格的完美转发。 - T.C.
在惰性求值提案中,使用c在使用点调用get<2>(move(e)),意味着string s = c;实际上会移出e,这似乎不直观。 - M.M
是的,他们肯定需要调整这部分代码,以某种方式使 c 保持为左值。 - T.C.
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接