我有一个应用程序,其中将一个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
成员不是严格必需的,但是在这里很方便,并且还提供了避免传递错误大小的数组的保证。手动确保其正确性很容易。
我的问题:
有没有办法从结构返回到数组表示形式?
如果没有,是否有另一种好方法可以将双精度数组转换为更具表现力的类型(这不太可能因更改使用的参数而引起问题)?我考虑过用枚举值索引数组,但它在各方面都不理想(需要手动更新转换函数和枚举定义,可能还需要所有这些枚举值的集合)...
答案 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))