C ++是否有标准的编译时类型容器?

时间:2015-02-27 16:30:33

标签: c++

This question得到Nim的回答,其中提及boost::mpl::map。)

标准C ++中是否有可以容纳类型的编译时容器?

用法示例如下:

compiler::vector foo{char, short, long, long long};

template <int N>
void bar(foo[N] param){/*do something and return foo[N]*/}

3 个答案:

答案 0 :(得分:3)

在c ++ 11中,您可以使用std :: tuple :(免责声明:未测试)

#include <tuple>
#include <type_traits>
std::tuple<char, short, long, long long> foo;

// reference type
template <int N>
void bar(decltype(std::get<N>(foo)) param){...}


// value type
template <int N>
void bar(std::remove_reference<decltype(std::get<N>(foo))>::type param)

请注意,这并不完全是您想要的,因为您将只有值或引用类型,即使两者都在foo的元组声明中混合。

永远不会使用元组的值。我认为通过编译器优化,foo实际上永远不会在目标代码中实现

答案 1 :(得分:3)

作为类型容器,标准为您提供std::tuple和 - 如bogdan所评论 - 您可以使用std::tuple_element访问类型元素。

using foo = std::tuple<char, short&, const long&&, long long>;

template <int N>
typename std::tuple_element<N,foo>::type bar(){/*...*/}

即使std::tuple_element不存在,您也可以轻松构建自己的:

/// We want a metafunction to accept an index N into our type list LIST
template <unsigned N, typename LIST> struct
tuple_element;

/// Specialization for the case where N==0
template <template <typename ...> class LIST_T,typename T,typename...ELMS> struct
tuple_element<0,LIST_T<T,ELMS...>> {
    using type = T; // just take the first type from the list
};

template <unsigned N, template <typename ...> class LIST_T,typename T,typename...ELMS> struct
tuple_element<N,LIST_T<T,ELMS...>> {
    /// fallback for N>0: delegate the result type recursively until N->0
    using type = typename tuple_element<N-1,LIST_T<ELMS...>>::type;
};

// create a convenience wrapper for the template
template <unsigned N, typename LIST> using
type_at = typename tuple_element<N, LIST>::type;

现在您可以定义类型列表,例如像这样:

using foo = std::tuple<char, short&, const long&&, long long>;

您可以使用type_at<N, foo>轻松访问它的元素:

static_assert(std::is_same< type_at<0,foo>, char>::value,"error");
static_assert(std::is_same< type_at<1,foo>, short&>::value,"error");
static_assert(std::is_same< type_at<2,foo>, const long&&>::value,"error");
static_assert(std::is_same< type_at<3,foo>, long long>::value,"error");

template <int N>
type_at<N,foo> bar(){/*...*/}

答案 2 :(得分:0)

这个版本是基于Bérenger的回答,它让我了解tuple概念。但我相信我们可以做得更好,甚至保留参考文献:

tuple foo<char&, short&, long&, long long&>;

template <int N>
void bar(tuple_element_t<N, decltype(foo)> param){}

事实上,如果没有计划在此函数之外使用foo,我们甚至可以将其声明为内联:

template <int N>
void bar(tuple_element_t<N, tuple<char&, short&, long&, long long&>> param){}