尝试实现std :: tie和std :: tuple的小版本

时间:2018-07-19 14:47:36

标签: c++ c++11 tuples std stdtuple

因此,正如标题所述,我正在尝试实现std::tiestd::tuple的小版本以供学习。

到目前为止,这是我的代码:

#include <iostream>

using namespace std;

template<typename T1, typename T2>
class Tuple
{
public:
    T1 t1;
    T2 t2;

    template<typename Tr1, typename Tr2>
    Tuple(Tr1 tr1, Tr2 tr2) : t1(tr1), t2(tr2)
    {
    }

    template<typename Tr1, typename Tr2>
    Tuple<T1, T2>& operator =(const Tuple<Tr1, Tr2>& other)
    {
        t1 = other.t1;
        t2 = other.t2;
        return *this;
    }
};

template<typename T1, typename T2>
Tuple<T1&, T2&> Tie(T1& t1, T2& t2)
{
    return Tuple<T1&, T2&>(t1, t2);
}

Tuple<int, int> f()
{
    return Tuple<int, int>(3, 5);
}

int main()
{
    int hi, bye;

    Tie(hi, bye) = f();

    cout << hi << " " << bye << '\n';
}

它几乎可以工作了(或者至少我认为是这样)。 我调试看到了

  • 已成功实例化Tuple(3,5)。然后,
  • 元组(引用hi和bye)已成功实例化。
  • 最后,调用赋值运算符,将后者分配给前者,即将引用分配给3和5。

但是一旦operator=返回,hibye就会有其未初始化的值:(

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

一个错误是operator=按值返回,而应按引用返回。但这不是原因。

原因是缺少T1T2中的构造函数,这导致它形成对值参数的引用。修复:

template<typename Tr1, typename Tr2>
Tuple(Tr1&& tr1, Tr2&& tr2) 
    : t1(std::forward<Tr1>(tr1))
    , t2(std::forward<Tr2>(tr2))
{}