首页 > 解决方案 > 使用 std::tie() 和赋值的评估顺序

问题描述

以下内容有效吗?

template <typename T>
std::pair<T, T> foo(T one, T two) { ... }

std::tie(one, two) = foo(std::move(one), std::move(two));

(假设所涉及的类以有效的方式处理分配给移出对象)。


通过阅读更新后的评估订单提案,我的假设是这是已修复的,但我无法在标准中找到一个准确的参考来验证这一点。有人可以帮忙提供吗?

标签: c++c++17language-lawyer

解决方案


标准中的相关部分可以在[expr.ass]/1中找到,它有

在所有情况下,赋值都在左右操作数的值计算之后和赋值表达式的值计算之前进行排序。右操作数在左操作数之前排序。对于不确定顺序的函数调用,复合赋值的操作是单次求值。

因此,根据this,foo(std::move(one), std::move(two));将首先评估,离开onetwo从对象移出一次std::tie(one, two)评估。 tie创建引用,因此无法访问从那里移动的对象。然后分配实际上发生意义one并被two分配给 viastd::tuple::operator =并获得返回的任何值foo。这是合法且定义明确的。


推荐阅读