$ curl cheat.sh/
/*
 * 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][1]:
 * 
 *  >     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`.
 * 
 *   [1]: http:en.cppreference.com/w/cpp/utility/tuple/operator%3D
 * 
 * [bolov] [so/q/43762651] [cc by-sa 3.0]
 */

$
Follow @igor_chubin cheat.sh