型リストのbackの簡単な実装

backだけならatよりずっと簡単に実装出来る事に気付いたので実装してみました。

#include <type_traits>
 
template <class... Types>
struct list {
 private:
  template <class, class... back_ts1>
  struct back_impl {
    template <class>
    using back_impl_t1 = void;
 
    template <class T>
    struct back_impl_t2 {
      using type = T;
    };
 
    template <class... back_impl_ts1>
    struct back_impl1 {
      template <class back_impl1_t>
      static back_impl1_t eval(back_impl_ts1*..., back_impl1_t*);
    };
 
    using type = typename decltype(back_impl1<back_impl_t1<back_ts1>...>::eval(
        static_cast<back_impl_t2<Types>*>(nullptr)...))::type;
  };
 
 public:
  using back = typename back_impl<Types...>::type;
};
 
int main() {
  using test = list<
      void, void, void, void, void, void, void, const double>;
  static_assert(std::is_same<test::back, const double>::value, "");
}