编写表达式
之间是否存在语义差异std::tie( x, y, z )
和以下表达式?
std::make_tuple( std::ref(x), std::ref(y), std::ref(z) )
如果是,那有什么区别?
顺便说一下,这个问题并不像What is the difference between assigning to std::tie
and tuple of references?那样问,因为引用的元组不是通过std::ref
创建的,而是通过显式指定类型。
答案 0 :(得分:18)
两个表达式之间几乎没有†功能差异。 tie()
只是更短,make_tuple()
更通用。
根据[tuple.creation],make_tuple
确实:
template<class... Types> constexpr tuple<VTypes...> make_tuple(Types&&... t);
对于类型中的每个
Ui
,decay_t<Ti>
为Ti
。如果Vi
等于VTypes
,则X&
中的Ui
reference_wrapper<X>
为Vi
,否则Ui
为std::make_tuple( std::ref(x), std::ref(y), std::ref(z) )
。
因此std::tuple<X&, Y&, Z&>
产生† a template<class... Types>
constexpr tuple<Types&...> tie(Types&... t) noexcept;
。
另一方面,tie
确实:
tuple<Types&...>(t...)
返回:
t
。当ignore
中的参数为std::tie(x, y, z)
时,将任何值分配给相应的元组元素都无效。
因此,std::tuple<X&, Y&, Z&>
也会产生delete b[d];
。
†除了一个edge case。
答案 1 :(得分:16)
如果x
,y
和z
中的任何一项是std::reference_wrapper
的专业化,则会有所不同。
#include <tuple>
#include <functional>
void f(std::reference_wrapper<int> x, int y, int z)
{
std::tie(x,y,z); // type is std::tuple<std::reference_wrapper<int>&, int&, int&>
std::make_tuple(std::ref(x),std::ref(y),std::ref(z)); // type is std::tuple<int&, int&, int&>
}