为 vardiac 和普通模板设置类型名称默认值

setting typename default value for vardiac and normal template

本文关键字:置类型 默认值 vardiac      更新时间:2023-10-16
template<typename T, T... Xs> class Nzm
{
private:
template<typename... Ts> static constexpr T Max(Ts... xs);
template<typename Tx> static constexpr T Max(Tx x)
{
    return x;
}
template<typename T1, typename T2, typename... Ts> static constexpr T Max(T1 x, T2 y, Ts... xs)
{
    return y > x ? Max<T2, Ts...>(y, xs...) : Max<T1, Ts...>(x, xs...);
}
public:
static const T Z = Max(Xs...);
};

int main() {
static_assert(Nzm<int,1,2,3,4,5,6>::Z==5,"XYZ");
return 0;
}

我已经知道所有的字体名都是int,我只想使用

Nzm<1,2,3,4,5,6> 

而不是

Nzm<int,1,2,3,4,5,6> 

这是用于编译时执行,没有代码或提示使其运行时。这可能吗?将所有这些类型名设置为 int ?

快速的解决方案是使用 using 声明来获取 int。

template<int... x>
using helper =  Nzm<int, x...>;
int main() {
    static_assert(helper<1, 2, 3, 4, 5, 6>::Z == 6, "XYZ");
    return 0;
}

另一种(更好的)方法是修改 Nzm 并将所有typename模板替换为int模板。参数和模板参数之间存在冗余,因此您可以摆脱参数。

template<int... Xs> class Nzm
{
private:
    template<int x> static constexpr int Max()
    {
        return x;
    }
    template<int x, int y, int... rest> static constexpr int Max()
    {
        return x > y ? Max<x, rest...>() : Max<y, rest...>();
    }
public:
    static const int Z = Max<Xs...>();
};
int main() {
    static_assert(Nzm<1, 2, 3, 4, 5, 6>::Z == 6, "XYZ");
    return 0;
}

如果你想要一个接受int参数包的模板,请给自己一个这样的模板:

template<int ...Is> class Nzm {
  // Your implementation follows
};

模板可以接受非类型的参数(其中包括整数参数),因此它们可以接受类似的参数包。