似乎std::tuple
包含一个或多个引用在构造和分配(尤其是复制/移动构造和复制/移动分配)方面具有意外行为。它不同于std::reference_wrapper
(更改引用的对象)和具有成员引用变量的结构(删除了赋值运算符)的行为。它允许方便的std::tie
python 像多个返回值,但它也允许明显不正确的代码,如下所示(链接在这里):
#include <tuple>
int main()
{
std::tuple<int&> x{std::forward_as_tuple(9)}; // OK - doesn't seem like it should be
std::forward_as_tuple(5) = x; // OK - doesn't seem like it should be
// std::get<0>(std::forward_as_tuple(5)) = std::get<0>(x); // ERROR - and should be
return 0;
}
该标准似乎要求或强烈暗示20.4.2.2.9
最新工作草案的复制(ish)分配部分中的这种行为(Ti&
将折叠为左值参考):
template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
9要求:
sizeof...(Types) == sizeof...(UTypes)
并且is_assignable<Ti&, const Ui&>::value
适用于所有i
.10效果:将 u 的每个元素分配给 *this 的对应元素。
11返回: *this
尽管 move(ish) 构造部分20.4.2.1.20
不太清楚(is_constructible<int&, int&&>
返回false
):
template <class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
18要求:
sizeof...(Types) == sizeof...(UTypes)
.19效果:对于 all ,构造函数用 with
i
初始化第i
th 个元素*this
std::forward<Ui>(get<i>(u))
。20备注:此构造函数不应参与重载决议,除非
is_constructible<Ti, Ui&&>::value
对 all 为真i
。构造函数是explicit
当且仅当is_convertible<Ui&&, Ti>::value
对于至少一个为假i
。
这些不是唯一受影响的小节。
问题是,为什么需要这种行为?另外,如果标准的其他部分在起作用,或者我误解了它,请解释我哪里出错了。
谢谢!