std::tie 是如何工作的? [英] How does std::tie work?

查看:25
本文介绍了std::tie 是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 std::tie 并没有考虑太多.它有效,所以我刚刚接受:

自动测试(){国际a, b;std::tie(a, b) = std::make_tuple(2, 3);//a 现在是 2,b 现在是 3返回 a + b;//5}

但是这个黑魔法是如何运​​作的?std::tie 创建的临时文件如何改变 ab ?我觉得这更有趣,因为它是一个库特性,而不是一个语言特性,所以它肯定是我们可以自己实现和理解的东西.

解决方案

为了阐明核心概念,让我们将其简化为更基本的示例.虽然 std::tie 对于返回(一组)更多值的函数很有用,但我们可以理解它只用一个值就可以了:

int a;std::tie(a) = std::make_tuple(24);返回一个;//24

为了继续前进,我们需要知道的事情:

  • std::tie 构造并返回一个引用元组.
  • std::tuplestd::tuple 是 2 个完全不同的类,它们之间没有联系,除了它们是从同一个模板生成,std::tuple.
  • tuple 有一个 operator= 接受不同类型(但相同编号)的元组,其中每个成员都被单独分配——来自 cppreference:

    <块引用>

    模板<类... UTypes >元组&运算符=(const tuple<UTypes...>&其他);

    (3) 对于所有的 i,将 std::get(other) 赋值给 std::get(*this).>

下一步是去掉那些只会妨碍你的函数,这样我们就可以将我们的代码转换成这样:

int a;std::tuple<int&>{a} = std::tuple<int>{24};返回一个;//24

下一步是查看这些结构内部究竟发生了什么.为此,我为 std::tuple<int>Tr 取代基 std::tuple<int& 创建了两种类型的 T 取代基;>,精简到我们操作的最低限度:

struct T {//取代 std::tuple;整数 x;};struct Tr {//std::tuple<int&> 的取代基内部&xr;自动运算符=(const T& other){//std::get(*this) = std::get(other);xr = 其他.x;}};自动 foo(){一个;Tr{a} = T{24};返回一个;//24}

最后,我喜欢把所有的结构都去掉(嗯,这不是 100% 等价的,但对我们来说已经足够接近了,并且足够明确以允许它):

自动 foo(){一个;{//临时变量的块替换//Tr{a}内部&tr_xr = a;//T{24}int t_x = 24;//= (赋值)tr_xr = t_x;}返回一个;//24}

所以基本上,std::tie(a) 初始化对a 的数据成员引用.std::tuple(24) 创建一个值为 24 的数据成员,并且赋值将 24 分配给第一个结构中的数据成员引用.但是由于该数据成员是绑定到 a 的引用,因此基本上将 24 分配给 a.

I've used std::tie without giving much thought into it. It works so I've just accepted that:

auto test()
{
   int a, b;
   std::tie(a, b) = std::make_tuple(2, 3);
   // a is now 2, b is now 3
   return a + b; // 5
}

But how does this black magic work? How does a temporary created by std::tie change a and b? I find this more interesting since it's a library feature, not a language feature, so surely it is something we can implement ourselves and understand.

解决方案

In order to clarify the core concept, let's reduce it to a more basic example. Although std::tie is useful for functions returning (a tuple of) more values, we can understand it just fine with just one value:

int a;
std::tie(a) = std::make_tuple(24);
return a; // 24

Things we need to know in order to go forward:

  • std::tie constructs and returns a tuple of references.
  • std::tuple<int> and std::tuple<int&> are 2 completely different classes, with no connection between them, other that they were generated from the same template, std::tuple.
  • tuple has an operator= accepting a tuple of different types (but same number), where each member is assigned individually—from cppreference:

    template< class... UTypes >
    tuple& operator=( const tuple<UTypes...>& other );
    

    (3) For all i, assigns std::get<i>(other) to std::get<i>(*this).

The next step is to get rid of those functions that only get in your way, so we can transform our code to this:

int a;
std::tuple<int&>{a} = std::tuple<int>{24};
return a; // 24

The next step is to see exactly what happens inside those structures. For this, I create 2 types T substituent for std::tuple<int> and Tr substituent std::tuple<int&>, stripped down to the bare minimum for our operations:

struct T { // substituent for std::tuple<int>
    int x;
};

struct Tr { // substituent for std::tuple<int&>
    int& xr;

    auto operator=(const T& other)
    {
       // std::get<I>(*this) = std::get<I>(other);
       xr = other.x;
    }
};

auto foo()
{
    int a;
    Tr{a} = T{24};

    return a; // 24
}

And finally, I like to get rid of the structures all together (well, it's not 100% equivalent, but it's close enough for us, and explicit enough to allow it):

auto foo()
{
    int a;

    { // block substituent for temporary variables

    // Tr{a}
    int& tr_xr = a;

    // T{24}
    int t_x = 24;

    // = (asignement)
    tr_xr = t_x;
    }

    return a; // 24
}

So basically, std::tie(a) initializes a data member reference to a. std::tuple<int>(24) creates a data member with value 24, and the assignment assigns 24 to the data member reference in the first structure. But since that data member is a reference bound to a, that basically assigns 24 to a.

这篇关于std::tie 是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆