Mar*_*cký 9 c++ boost boost-variant boost-mpl c++11
我很乐意得到并建议如何以"二维方式"处理boost :: variant.听起来很奇怪,但让我的代码说更多(希望如此):
我编写了一个名为Parameter的类:
template<typename PARAM_TYPE, typename DATA_TYPE=double>
class Parameter : public quantity<PARAM_TYPE, DATA_TYPE>
{
...
}
Run Code Online (Sandbox Code Playgroud)
上面定义的参数的示例用法:
Parameter<si::length, double> SampleParameter1;
Parameter<si::dimensionless, short> SampleParameter2;
Run Code Online (Sandbox Code Playgroud)
当我试图通过上面的例子解释时,我可以使用boost::units::si::???和不同的数据类型double, short, int等定义几个参数类型.
我的目标是构建一个std::map可以存储任何Parameter类型实例的容器(如上所示).
因此我宣布:
typedef boost::variant<Parameter<si::dimensionless, short>, Parameter<si::length, double> > SupportedParameterTypes;
std::map<int, SupportedParameterTypes> myMapStorage;
Run Code Online (Sandbox Code Playgroud)
这很好用,但有一个很大的缺点我想解决 - 我必须定义参数类型的每一个组合我想支持SupportedParameterTypes上面定义的类型.
我的想法是定义boost :: mpl :: vector,保留我想支持的所有参数类型:
typedef boost::mpl::vector<si::dimensionless, si::length> ParameterTypes;
Run Code Online (Sandbox Code Playgroud)
另一方面,支持所有可能的参数数据类型:
typedef boost::mpl::vector<short, int, float, double> ParameterDataTypes;
Run Code Online (Sandbox Code Playgroud)
我遇到了麻烦:
typedef typename boost::make_variant_over<ParameterTypes>::type ParameterTypeVariants;
typedef typename boost::make_variant_over<ParameterDataTypes>::type ParameterDataVariants;
typedef boost::variant<Parameter<ParameterTypeVariants, ParameterDataVariants> > SupportedParameterTypes;
Run Code Online (Sandbox Code Playgroud)
但是定义boost::variant一些Parameter由其他人定义的东西boost::variant似乎不起作用:o(
问题:如何定义std::map容器,保存Parameter在适当的boost::mpl::vectors中定义的所有类型?
我想请你帮忙解决这个问题.也许根据我写的编码它是不是一个好主意/原则,谁知道.我的目标是通过std :: map灵活存储,以便能够保存我的所有参数,而不会使我的代码模糊不清.寻找智能解决方案当然:o)
非常感谢您对我的问题/请求帮助的任何回复
你可以用类似的东西来产生所有的配对
template <typename Seq, typename T1, typename T2>
struct cartesian_parameters_helper;
template <std::size_t...Is, typename T1, typename T2>
struct cartesian_parameters_helper<std::index_sequence<Is...>, T1, T2>
{
static constexpr std::size_t size1 = std::tuple_size<T1>::value;
using type = boost::variant<
Parameter<
std::tuple_element_t<Is / size1, T1>,
std::tuple_element_t<Is % size1, T2>
>...>;
};
template <typename T1, typename T2>
struct cartesian_parameters
{
using type = typename cartesian_parameters_helper<
std::make_index_sequence<std::tuple_size<T1>::value
* std::tuple_size<T2>::value>,
T1, T2>::type;
};
Run Code Online (Sandbox Code Playgroud)
然后将其用作
using SupportedParameterTypes =
cartesian_parameters<std::tuple<si::dimensionless, si::length>,
std::tuple<short, int, float, double>>::type;
Run Code Online (Sandbox Code Playgroud)