stdlib是否提供类型列表?

时间:2019-06-16 11:17:15

标签: c++ template-meta-programming c++-standard-library

在现代C ++中,标准库是否提供类型列表模板?

int main() {
    using int_types = type_list<int,long,short,char>;
    std::cout << length<int_types>::value << ' '
              << typeid(element<2,int_types>::type).name();
}

请注意,int_types不存储任何值(与std::tuple一样)。它只是类型列表。

3 个答案:

答案 0 :(得分:3)

在我看来,在现代C ++标准库中,您想要的最接近std::tuple

如果问题是std::tuple存储所列类型的值(因此,我想可能是实例化该类型的对象的问题),则很容易编写一个包装std::tuple的可实例化对象using而不实例化std::tuple本身。

我的意思是……给了这样的包装纸

template <typename ... Ts>
struct wrapTuple
 {
   using type = std::tuple<Ts...>;

   template <std::size_t N>
   using element = std::tuple_element_t<N, type>;

   static constexpr auto length { std::tuple_size_v<type> };
 };

您可以编写以下几行而无需实例化包装器

   using int_types = wrapTuple<int, long, short, char>;

   std::cout << int_types::length << ' '
      << typeid(int_types::element<2u>).name() << std::endl;

但是您也可以实例化它而无需实例化std::tuple

   int_types it;

   std::cout << it.length << ' '
      << typeid(decltype(it)::element<2u>).name() << std::endl;

答案 1 :(得分:2)

使用std::tuple类型,但不要实例化它:

#include <iostream>
#include <tuple>

int main()
{
    using int_types = std::tuple<int, long, short, char>;
    std::cout << std::tuple_size_v<int_types> << ' '
        << typeid(std::tuple_element_t<2, int_types>).name();
}

MSVC输出:

4 short

GCC输出:

4 s

C语输出:

4 s

答案 2 :(得分:0)

最后,我做了这样的事情:

template<typename ...T> struct type_list {};

template<typename    L> struct length;
template<typename ...T> struct length<type_list<T...>> {static const std::size_t value=sizeof...(T);};

template<std::size_t I, typename L>
struct element;
template<typename F, typename ...T> 
struct element<0, type_list<F, T...>> {using type=F;};
template<std::size_t I> 
struct element<I, type_list<>>        {using type=void;};
template<std::size_t I, typename F, typename ...T> 
struct element<I, type_list<F, T...>> {using type=typename element<I-1,type_list<T...>>::type;};

int main() {
    using int_types = type_list<int,long,short,char>;
    std::cout << length<int_types>::value << '\n'
              << typeid(element<2,int_types>::type).name() << '\n';
    return 0;
}