Adham Zahran
Adham Zahran

Reputation: 2180

Trying to implement a small version of std::tie and std::tuple

So as the title says I'm trying to implement a small version of std::tie and std::tuple for learning purposes.

Here's my code so far:

#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';
}

It's almost working (or at least I think it is). I debug to see that

But once the operator= returns, hi and bye would just have their uninitialized values :(

What am I doing wrong?

Upvotes: 0

Views: 122

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136525

One mistake is that operator= returns by value, whereas it should return by reference. But this is not the cause.

The cause is that a constructor from T1 and T2 is missing, which causes it to form references to value arguments. Fix:

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

Upvotes: 2

Related Questions