键入返回所选类型元组的函数

时间:2015-06-22 11:27:43

标签: c++ templates c++11 metaprogramming

我已经实现了一个类型函数Tuple,可将My_enum值列表转换为相应类型的std::tuple

#include <tuple>

enum My_enum{ t_int, t_double };

// Bind_type is a type function that given a My_enum returns the corresponding type
template<My_enum E> struct Bind_type;
template<> struct Bind_type<t_int>{ using type = int; };
template<> struct Bind_type<t_double>{ using type = double; };

// Tuple is a type function that given a template value parameter pack of My_enums returns a std::tuple of correspondig types
template<My_enum First, My_enum... Others>
struct Tuple {
    using type = decltype(std::tuple_cat(
                typename Tuple<First>::type{},
                typename Tuple<Others...>::type{}
            ));
};

template<>
struct Tuple<t_int> {
    using type = std::tuple<Bind_type<t_int>::type>;
};
template<>
struct Tuple<t_double> {
    using type = std::tuple<Bind_type<t_double>::type>;
};

我希望能够一次性为Tuple声明递归基本情况,因为只要我添加或删除值,我就不想手动管理Tuple特化My_enum,因为它容易出错(而且很无聊)。我试过了:

template<My_enum E>
struct Tuple {
    using type = std::tuple<Bind_type<E>::type>;
};

但这不是可变版本的有效专业。

我的问题是:当Tuple只有一个模板值参数时,是否有一种聪明的方式来声明<?php if (database_querySelect($sql,$rows)) { $spCounter = 0; ?> <div class="panel"> <div class="panel-heading"> <h4><?php print translate("Related Products"); ?></h4> </div> <div id="relatedSlider" class="carousel slide"> <div class="carousel-inner"> <div class="item active"> <?php foreach($searchresults["products"] as $product): ?> <?php include("html/search/style1.php"); ?> <?php if(($spCounter) % 3 == 0) : ?> </div> <div class="item"> <?php endif; ?> <?php $spCounter++; endforeach; ?> </div> </div> </div> </div> <?php } ?> 的特化?

1 个答案:

答案 0 :(得分:6)

只需将参数包直接扩展为std::tuple即可无需递归即可完成此操作:

template<My_enum... Enums>
struct Tuple {
    using type = std::tuple<typename Bind_type<Enums>::type...>;
};

要更直接地回答您的问题,您可以声明一个可变参数主模板,然后编写两个特化:当至少有两个参数时,以及何时只有一个:

//primary template, takes any number of My_enums
template <My_enum... Enums>
struct Tuple {
    //this case will be chosen if we instantiate a Tuple with no args
    using type = std::tuple<>;
}

//specialization for when there are at least two arguments
template<My_enum First, My_enum Second, My_enum... Others>
struct Tuple<First,Second,Others...> {
    using type = decltype(std::tuple_cat(
                typename Tuple<First>::type{},
                typename Tuple<Second,Others...>::type{}
            ));
};

//base case, only one argument left
template<My_enum Last>
struct Tuple<Last> {
    using type = std::tuple<typename Bind_type<Last>::type>;
};