c++ - 如何在 "two dimensional manner"中使用 boost::variant 定义异构 std::map

标签 c++ c++11 boost boost-mpl boost-variant

我很乐意得到并建议如何以“二维方式”处理 boost::variant。听起来很奇怪,但让我的代码说得更多(希望如此):

我编写了一个名为 Parameter 的类:

template<typename PARAM_TYPE, typename DATA_TYPE=double>
class Parameter : public quantity<PARAM_TYPE, DATA_TYPE>
{
...
}

上面定义的我的参数的示例用法:

Parameter<si::length, double> SampleParameter1;
Parameter<si::dimensionless, short> SampleParameter2;

正如我试图通过上面的示例解释的那样,我可以使用 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;

这很好用,但有一个我想解决的大缺点 - 我必须定义我想在上面定义的 SupportedParameterTypes 类型中支持的每个参数类型组合。

我的想法是定义包含我想要支持的所有参数类型的 boost::mpl::vector:

typedef boost::mpl::vector<si::dimensionless, si::length> ParameterTypes;

另一方面,支持所有可能的参数数据类型:

typedef boost::mpl::vector<short, int, float, double> ParameterDataTypes;

我的烦恼来了:

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;

但是要定义由其他一些 boost::variant 定义的东西(Parameter)的 boost::variant 似乎不起作用:o(

问题:如何定义 std::map 容器,其中包含我在适当的 boost::mpl 中定义的所有 Parameter 类型: :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;
};

然后将其用作

using SupportedParameterTypes =
    cartesian_parameters<std::tuple<si::dimensionless, si::length>,
                         std::tuple<short, int, float, double>>::type;

Demo

关于c++ - 如何在 "two dimensional manner"中使用 boost::variant 定义异构 std::map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34263391/

相关文章:

c++ - 为什么 gcc 会在全局命名空间中隐藏重载函数?

c++ - 在无向图中找到一个环(boost)并返回它的顶点和边

boost - 如何只连接一次 boost 信号?

C++::Boost::Regex 迭代子匹配

C++ 无处引用

c++ - 读取数组末尾是否安全?

c++ - 如何克隆外部(来自 git)cmake 项目并将其集成到本地项目中

c++ - 元组的一个元素可以引用另一个元素吗?

c++ - 带有对 type_info 的引用的 std::common_type

c++ - 如何知道何时通过 C++ 11 上的终端管道输入?