自动从元组/数组转换为结构...然后返回?

时间:2018-08-01 16:24:49

标签: c++

我有一个应用程序,其中将一个std::array<double, N>交给我,其中每个double是一个不同的(或多或少无关的)参数。仅举例来说,它们可以表示压力,距离和安全系数。

由于这些参数的数量和含义在开发过程中可能会发生变化,因此我想在执行其他操作之前将其转换为不太容易出错的表示形式,例如,这样的结构:

struct Params
{
  double pressure, distance, safetyFactor;
};

从那以后,任何人搞砸的可能性都很小。

在没有关于结构布局等的进一步假设的情况下,std::memcpy是不可能的(而且我们甚至不用考虑严格的别名冲突)。手动编写和更新转换功能将很繁琐,并且容易引入错误。

我注意到,您可以通过将花括号初始化与参数包扩展相结合,自动将此数组(以及可能的任何元组)转换为匹配的结构:

template<class T, class Array, std::size_t... Is>
T toTyped_impl(const Array& arr, std::index_sequence<Is...>)
{
    return { arr[Is]... };
}

template<class T>
T toTyped(std::array<double, T::Dim> arr)
{
    return toTyped_impl<T>(arr, std::make_index_sequence<T::Dim>());
}


struct Params
{
  static constexpr unsigned Dim = 3;
  double pressure, distance, safetyFactor;
};

Params foo()
{
    return toTyped<Params>({1, 2.0, 3});
}

Dim成员不是严格必需的,但是在这里很方便,并且还提供了避免传递错误大小的数组的保证。手动确保其正确性很容易。

我的问题:
有没有办法从结构返回到数组表示形式?

如果没有,是否有另一种好方法可以将双精度数组转换为更具表现力的类型(这不太可能因更改使用的参数而引起问题)?我考虑过用枚举值索引数组,但它在各方面都不理想(需要手动更新转换函数枚举定义,可能还需要所有这些枚举值的集合)...

2 个答案:

答案 0 :(得分:1)

一种简单的方法是使用有意义的吸气剂

struct Params
{
    double pressure() const { return data[0]; }
    double& pressure() { return data[0]; }

    double distance() const { return data[1]; }
    double& distance() { return data[1]; }

    double safetyFactor() const { return data[2]; }
    double& safetyFactor() { return data[2]; }

    std::array<double, 3> data;
};

因此您可以同时访问。

答案 1 :(得分:1)

您可能想要的是融合后的序列:

#include <boost/fusion/adapted.hpp>

BOOST_FUSION_ADAPT_STRUCT(
    Params,
    (double, pressure)
    (double, distance)
    (double, safetyFractor))