代码之家  ›  专栏  ›  技术社区  ›  Max Langhof

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

c++
  •  -1
  • Max Langhof  · 技术社区  · 6 年前

    我有一份申请,在那里我得到了一份 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 回复  |  直到 6 年前
        1
  •  1
  •   Jarod42    6 年前

    一个简单的方法是使用有意义的getter

    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;
    };
    

    所以你们都有机会。

        2
  •  1
  •   alfC    6 年前

    你可能想要一个融合适应序列:

    #include <boost/fusion/adapted.hpp>
    
    BOOST_FUSION_ADAPT_STRUCT(
        Params,
        (double, pressure)
        (double, distance)
        (double, safetyFractor))