0

我正在尝试编写具有以下功能的某个类。

在外面,我有一组定义类型和成员函数的类:

class X
{
public:
    using energy_t = std::array<double,N>; // N is some number 1,2,3...
    energy_t calc_energy(/*params*/);

    // everything else
};

我想创建一个类模板,它可以包含这些小类的不同组合并在它们上调用一些功能。energy_t要求是此类集合中的所有s 都是相同的。这是第一种方法:

template<typename Part, typename... Parts>
requires (std::is_same_v<typename Part::energy_t, typename Parts::energy_t> && ...)
class State
{
public:
    static constexpr int degeneracy = std::tuple_size_v<typename Part::energy_t>;
    // right now is deduced from given types
    using energy_t = std::array<double, degeneracy>;

private:
    std::tuple<Part, Parts...> _parts;

public:
    State(Part&& part, Parts&&... parts) : _parts(part, parts...) {}

    // functionality, usually with std::apply() on _parts tuple member
}

这几乎可以满足所有需求,并且可以使用 CTAD 很好地实例化(这很重要,因为某些参数不是默认可构造的):

State state{X(), Y(/*ctor-params*/), Z()};

问题:目前,唯一检查的是所有energy_t = std::array<double,N>s 都相同。但是,没有具体说明N需要什么数量。这将是构造的“完美”语法:

State<3> state{X(), Y(/*params*/), Z()};
// only types with energy_t = std::array<double,3> are accepted

因为它只是一个明确的陈述:State<3>是一个三重退化状态,{X(), Y(), ...}其部分是就地构建的。

但是,这似乎是不可能的,因为禁止只指定模板参数的一部分。

想到的一件事就是将另一个模板参数添加到构造函数中并继续执行 CTAD,例如

template<size_t N, typename Part, typename Parts...>
class State
{
    State(size_t N, Part&& part, Parts&&... parts) : _parts(part, parts) {};
    // etc
};

State state{3, X(), Y()};

还有其他方法可以解决这个问题吗?

4

0 回答 0