如何从参数包中定义值类型的元组

时间:2017-06-14 06:08:53

标签: c++ tuples variadic-templates boost-hana

我需要构建一个n类型的元组。这n种类型是n种其他类型的值类型。请考虑以下代码段:

#include <boost/hana.hpp>

namespace hana = boost::hana;

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    hana::tuple<Types...> sets;
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done?
};

应用程序的目的是这样的:我向这个类传递一个可能不同类型的容器的参数包。该类将这些容器放入元组sets。该类还有一个字段combination,它是容器传递给类的元素数量的元组。但元素的类型是不同容器的值类型。

该类旨在懒惰地构建传递给它的容器的笛卡尔积,并将当前组合存储在combination中。但是,我怎样才能以可变方式实际获取容器的值类型?

2 个答案:

答案 0 :(得分:12)

当然可以做到。您只需要适当地声明包扩展。

#include <vector>
#include <map>
#include <tuple>

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    std::tuple<Types...> sets;
    std::tuple<typename Types::value_type...> combination; 
};


int main() {
    std::vector<int> i;
    std::map<int, std::vector<int>> m;

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>>
      c(i, m);

    return 0;
}

请注意typename说明符的必需用法。经验法则是将包名称视为单一类型。应用相同的语法/语义约束,因为我们必须指定我们使用范围解析运算符访问类型。然后在最后加强包装扩展。

Live Example

function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
    const copy = {} as Pick<T, K>;

    keys.forEach(key => copy[key] = obj[key]);

    return copy;
}

const a = { a: 1, b: '2' };
let copy : A = pick(a, "a");
console.log(copy);

答案 1 :(得分:5)

扩展StoryTeller的正确答案(请接受他的回答):

我发现通过在翻译元函数方面实现它们,可以更容易地将这种类型的翻译可视化,例如:

var id=$("#hidden_id").val();
    $('#calendar').fullCalendar({
         defaultView: 'agendaWeek',

            header: {
                    left: '',
                    center: 'prev title next',                
                    right: ''
            },
            /*          
                loading: function (bool) {
                        $("#loading_div").show();
                },
            */
            defaultDate: "<?php echo date('Y-m-d');?>",
            navLinks: true, // can click day/week names to navigate views
            editable: false,
            events: "json_rate-info/"+id,
            allDay: true,
            selectable: true,
            selectHelper: true,
      });