So I introduced myself to templates in C++11 and I have to say it's really confusing, but also very fascinating.  I just need to get my head around what happens at compile time so that I don't wind up making one line of driver code amount to a megabyte of asm...Anyway, to teach myself I wrote a little container class.  It's a container that locks and unlocks a mutex on each read/write operation on a group of data.  There's still a few features I want to add to it, but that will take a lot of forced templating beyond compile-time recursion (more on this at the end).Here is the code (updated 11/5):#include <mutex>#include <tuple>#include <cstring>#include pack_size.hpp#include pack_size_index.hpp#include pod_test.hpptemplate <typename... item_t> class lockbox {    static_assert(sizeof...(item_t) > 0, empty lockboxes are not permitted.);private:    pod_test<item_t...> _test; //No data, tests to make sure item_t parameters are pod-only    public: char _items[pack_size<item_t...>::value];    std::mutex _mutex;    template <size_t index, typename type_t, typename... args>    static inline const void set_all(char* dest, const type_t& value, const args&... values) {        type_t* align = (type_t*)&dest[pack_size_index<index, item_t...>::value];        *align = value;        set_all <index + 1, args...> (dest, values...);    }    template <size_t index, typename type_t>    static inline const void set_all(char* dest, const type_t& value) {        type_t* align = (type_t*)&dest[pack_size_index<index, item_t...>::value];        *align = value;    }    template <size_t index, typename type_t, typename... args>    static inline const void get_all(char* src, type_t& value, args&... values) {        type_t* align = (type_t*)&src[pack_size_index<index, item_t...>::value];        value = *align;        get_all <index + 1, args...> (src, values...);    }    template <size_t index, typename type_t>    static inline const void get_all(char* src, type_t& value) {        type_t* align = (type_t*)&src[pack_size_index<index, item_t...>::value];        value = *align;    }    template <size_t index, size_t... indices>    static inline const void set_indices(char* dest,                                         typename std::tuple_element<index, std::tuple<item_t...> >::type& value,                                         typename std::tuple_element<indices, std::tuple<item_t...> >::type&... values) {        typedef typename std::tuple_element<index, std::tuple<item_t...> >::type type_t;        type_t* align = (type_t*)&dest[pack_size_index<index, item_t...>::value];        *align = value;        set_indices <indices...> (dest, values...);    }    template <size_t index>    static inline const void set_indices(char* dest,                                         typename std::tuple_element<index, std::tuple<item_t...> >::type& value) {        typedef typename std::tuple_element<index, std::tuple<item_t...> >::type type_t;        type_t* align = (type_t*)&dest[pack_size_index<index, item_t...>::value];        *align = value;    }    template <size_t index, size_t... indices>    static inline const void get_indices(char* src,                                         typename std::tuple_element<index, std::tuple<item_t...> >::type& value,                                         typename std::tuple_element<indices, std::tuple<item_t...> >::type&... values) {        typedef typename std::tuple_element<index, std::tuple<item_t...> >::type type_t;        type_t* align = (type_t*)&src[pack_size_index<index, item_t...>::value];        value = *align;        get_indices <indices...> (src, values...);    }    template <size_t index>    static inline const void get_indices(char* src,                                         typename std::tuple_element<index, std::tuple<item_t...> >::type& value) {        typedef typename std::tuple_element<index, std::tuple<item_t...> >::type type_t;        type_t* align = (type_t*)&src[pack_size_index<index, item_t...>::value];        value = *align;    }public:    lockbox(void) {        _mutex.lock();        memset(_items, 0, pack_size<item_t...>::value);        _mutex.unlock();    }    inline lockbox(const lockbox<item_t...>& other) {        operator=(other);    }    lockbox(item_t... items) {        _mutex.lock();        set_all <0, item_t...> (_items, items...);        _mutex.unlock();    }    ~lockbox(void) {}    lockbox<item_t...>& operator= (lockbox<item_t...>& rhs) {        char buffer[pack_size<item_t...>::value];        rhs._mutex.lock();        memcpy(buffer, rhs._items, pack_size<item_t...>::value);        rhs._mutex.unlock();        _mutex.lock();        memcpy(_items, buffer, pack_size<item_t...>::value);        _mutex.unlock();        return *this;    }    lockbox<item_t...>& set(item_t... items) {        _mutex.lock();        set_all <0, item_t...> (_items, items...);        _mutex.unlock();        return *this;    }    template <size_t... indices>    lockbox<item_t...>& set(typename std::tuple_element<indices, std::tuple<item_t...> >::type... values) {        _mutex.lock();        set_indices <indices...> (_items, values...);        _mutex.unlock();        return *this;    }    inline lockbox<item_t...>& set(lockbox<item_t...>& other) {        return operator=(other);    }    lockbox<item_t...>& get(item_t&... ref_items) {        _mutex.lock();        get_all <0, item_t...> (_items, ref_items...);        _mutex.unlock();        return *this;    }    template <size_t... indices>    lockbox<item_t...>& get(typename std::tuple_element<indices, std::tuple<item_t...> >::type&... ref_values) {        _mutex.lock();        get_indices <indices...> (_items, ref_values...);        _mutex.unlock();        return *this;    }    inline lockbox<item_t...>& get(lockbox<item_t...>& other) {        return other = *this;    }    static inline const size_t bytes(void) {        return pack_size<item_t...>::value;    }};pack_size:template <typename... args> struct pack_size;template <> struct pack_size <> {    static const size_t value = 0;};template <typename type_t, typename... args> struct pack_size <type_t, args...> {    static const size_t value = sizeof(type_t) + pack_size<args...>::value;};pack_size_index:template <size_t index, typename... args> struct pack_size_index;template <size_t index, typename type_t, typename... args> struct pack_size_index <index, type_t, args...> {    static_assert(sizeof...(args) > 0, index specified is out of bounds.);    static constexpr size_t value = sizeof(type_t) + pack_size_index<index - 1, args...>::value;};template <typename type_t, typename... args> struct pack_size_index <0, type_t, args...> {    static constexpr size_t value = 0;};pod_test:#include <type_traits>template <typename... args> struct pod_test;template <typename type_t, typename... args> struct pod_test<type_t, args...> {    static_assert(std::is_pod<type_t>::value, parameter pack contains non-pod types.);    static pod_test<args...> node;};template <typename type_t> struct pod_test<type_t> {    static_assert(std::is_pod<type_t>::value, parameter pack contains non-pod types.);};Usage:#include lockbox.hppint main(int argc, char** argv) {    lockbox<float, double> box(3.5f, 6.7777899);    float a;    double b;    lockbox.get<0, 1>(a, b) //get the items at indices 0 and 1 and                            //store them in the variables specified    std::cout << a << ,  << b << std::endl; //output: 3.5, 6.7777899    lockbox.set<1> (5.67); //set the item at index 1 to the value specified    lockbox.get(a, b) //get all items and store them in the variables                      //specified (works the same with set as well)    std::cout << a << ,  << b << std::endl; //output: 3.5, 5.67    return 0;}What inefficiencies are present here?  I think set_all, get_all, set_indices, and get_indices might be creating an inordinate amount of functions, but that's all I can think of.  Is my format readable, naming conventions and spacing considered?
lockbox (a boost-like container)
c++;c++11;template meta programming