I have written a simple (read: incomplete) tuple implementation that, AFAICT, does not violate the standard layout requirements. It's largely based on Nish's implementation, but I use a recursive hierarchy of nested members, rather than recursive inheritance. Unfortunately this approach necessitates recursion for element access.  But for my purposes I am willing to sacrifice compilation time for a predictable memory layout... my tuple stores elements in the correct order.Aside from lengthy compilation times, are there any obvious flaws to this approach?#include <cstddef>#include <type_traits>template <class... Ts>struct tuple;template <class T, class... Ts>struct tuple<T, Ts...>{    T first;    tuple<Ts...> rest;  };template <class T>struct tuple<T>{    T first;};namespace detail {    template < ::std::size_t i, class T>    struct tuple_element;    template < ::std::size_t i, class T, class... Ts>    struct tuple_element<i, tuple<T, Ts...> >        : tuple_element<i - 1, tuple<Ts...> >    {};    template <class T, class... Ts>    struct tuple_element<0, tuple<T, Ts...> >    {        using type = T;    };    template < ::std::size_t i>    struct tuple_accessor    {        template <class... Ts>        static inline typename tuple_element<i, tuple<Ts...> >::type & get (tuple<Ts...> & t)        {            return tuple_accessor<i - 1>::get(t.rest);        }        template <class... Ts>        static inline const typename tuple_element<i, tuple<Ts...> >::type & get (const tuple<Ts...> & t)        {            return tuple_accessor<i - 1>::get(t.rest);        }    };    template <>    struct tuple_accessor<0>    {        template <class... Ts>        static inline typename tuple_element<0, tuple<Ts...> >::type & get (tuple<Ts...> & t)        {            return t.first;        }        template <class... Ts>        static inline const typename tuple_element<0, tuple<Ts...> >::type & get (const tuple<Ts...> & t)        {            return t.first;        }    };    template <class T, class... Ts>    struct tuple_builder    {        static inline void make (tuple<typename ::std::decay<T>::type, typename ::std::decay<Ts>::type...> & t, T && x, Ts &&... xs)        {            t.first = x;            tuple_builder<Ts...>::make(t.rest, ::std::forward<Ts>(xs)...);        }    };    template <class T>    struct tuple_builder<T>    {        static inline void make (tuple<typename ::std::decay<T>::type> & t, T && x)        {            t.first = x;        }    };} // namespace detailtemplate <class... Ts>inline tuple<typename ::std::decay<Ts>::type...> make_tuple (Ts &&... x){    tuple<typename ::std::decay<Ts>::type...> t;    detail::tuple_builder<Ts...>::make(t, ::std::forward<Ts>(x)...);    return t;}template < ::std::size_t i, class... Ts>inline typename detail::tuple_element<i, tuple<Ts...> >::type & get (tuple<Ts...> & t){    return detail::tuple_accessor<i>::get(t);}template < ::std::size_t i, class... Ts>inline const typename detail::tuple_element<i, tuple<Ts...> >::type & get (const tuple<Ts...> & t){    return detail::tuple_accessor<i>::get(t);}static_assert(::std::is_standard_layout<tuple<bool, int, float, char, double, tuple<int, char> > >(), Compiler is stupid);For more context, see this
Standard-layout tuple implementation
c++;c++11
Minor issues:You need to include <utility> for std::forward.You don't support empty tuples. It's obviously not a huge problem, but adding one line template <> struct tuple<> {};is no great burden either.You should be using std::forward for the assignments in the make functions:t.first = std::forward<T>(x);so move assignment is used when x is an rvalue reference.Slightly bigger issue:Having no constructors in tuple means that your tuple can never contain a type that is not default constructible. Default construction followed by assignment is inherently less efficient than value construction. I would write perfect forwarding constructors for the tuple specializations, something like:template <class T, class... Ts>struct tuple<T, Ts...>{    T first;    tuple<Ts...> rest;    tuple() = default;    template <class U, class...Us, class=      typename ::std::enable_if<        !::std::is_base_of<          tuple,          typename ::std::decay<U>::type        >::value      >::type    >    tuple(U&& u, Us&&...tail) :      first(::std::forward<U>(u)),      rest(::std::forward<Us>(tail)...) {}};template <class T>struct tuple<T>{    T first;    tuple() = default;    template <class U, class=      typename ::std::enable_if<        !::std::is_base_of<          tuple,          typename ::std::decay<U>::type        >::value      >::type    >    tuple(U&& u) :      first(::std::forward<U>(u)) {}};(All that enable_if junk is to keep the perfect forwarding constructors from being used for copy/move construction from another tuple.) This allows make_tuple to become a one-liner:return tuple<typename ::std::decay<Ts>::type...>(::std::forward<Ts>(x)...);(Code demo with suggested changes and the now-unnecessary builder templates removed)