我有一个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::accumulate
和boost::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;
}