c++ - std::tie 是如何工作的?

标签 c++ c++11 tuples

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

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
}

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

最佳答案

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

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

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

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

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

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

下一步是摆脱那些只会妨碍您的功能,因此我们可以将代码转换为:

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

下一步是确切了解这些结构内部发生了什么。 为此,我创建了 2 种类型 T std::tuple<int> 的取代基和 Tr取代基std::tuple<int&> ,为我们的运营精简到最低限度:

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
}

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

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
}

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

关于c++ - std::tie 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43762651/

相关文章:

c++ - 在这种情况下是 clang 错误、gcc 错误还是两者都错误 - 用成员指针抛弃 constness

c++ - 在模板函数中使用 const 迭代器

c++ - 如何测试B类是否派生自A类?

c++11 - std::shared_ptr 和 dlopen(),避免未定义的行为

c++ - 标准输入C++

python - 将数据帧绑定(bind)到 for 循环中的变量会将其转换为元组?

c++ - 如何使用 VS Debugger 找出模板参数的类型?

C++:带有删除器的类的前向声明,用于可重复的唯一指针

c++ - unordered_map/unordered_set 中元组的通用哈希

F# - 如何从 n-1 元组和 1 创建 n 元组