没有构造的元组类型的运行时迭代

时间:2015-11-30 03:16:32

标签: algorithm c++11 boost-fusion typeinfo

我有一个std::tuple(或一个boost融合元组),其元素不能简单地构造(例如引用),我想迭代类型但不是迭代元件。

在这个例子中,我有一个(通用)元组类型,我想生成一个带有(运行时)类型信息的向量。如果序列中的所有类型都是普通的默认构造但不是一般的,则下面的示例有效。

总之,我想要一个转换函数:std::tuple<...> -> std::vector<std::type_index>

#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <typeindex>
#include<vector>

using tuple_type = std::tuple<std::string&, int>;

int main(){
    std::vector<std::type_index> types;
    boost::fusion::for_each(
        tuple_type{},  // fails because of std::string&
        [&types](auto& e){types.push_back(typeid(e));} 
    ); 
}

问题是我必须从非运行时信息生成运行时信息,我无法弄清楚如何混合融合函数(http://www.boost.org/doc/libs/1_59_0/libs/fusion/doc/html/fusion/algorithm/iteration/functions.html)和元函数(http://www.boost.org/doc/libs/1_41_0/libs/fusion/doc/html/fusion/algorithm/iteration/metafunctions.html)。

我尝试使用boost::fusion::accumulateboost::fold,但情况总是相同的,在某些时候我必须生成运行时元素才能应用算法。

编辑:我解决了原始问题(std::tuple<...> -> std::vector<std::type_index>)。我无法想象目前的另一个背景,但也许基本问题仍然存在。

我是通过使用涉及在typeid(或std::vector)的构造函数中的std::array函数上展开参数包的技巧来实现的。

template<class... Args>
std::array<std::type_index, sizeof...(Args)> const& types_info<std::tuple<Args...>>::value{typeid(Args)...};

完整的代码就是这样(请注意,我还决定使用std::array)。

#include <typeindex>
#include<array>
#include<iostream>

template<class T>
struct types_info;

template<class... Args>
struct types_info<std::tuple<Args...>>{
    static std::array<std::type_index, sizeof...(Args)> const& value;//{typeid(Args)...};
};

template<class... Args>
std::array<std::type_index, sizeof...(Args)> const& types_info<std::tuple<Args...>>::value{typeid(Args)...};

// vvv works only in C++1z
template<template<typename...> typename T, class... Args> // non tuples types as well
struct types_info<T<Args...>> : types_info<std::tuple<Args...>>{};

using tuple_type = std::tuple<std::string&, int>;

int main(){

    std::vector<std::type_index> types;

    std::cout << types_info<tuple_type>::value.size() << std::endl;
    std::cout << types_info<std::map<int, std::string>>::value.size() << std::endl;
}

0 个答案:

没有答案