为vardiac和普通模板设置typename默认值

时间:2017-01-04 18:27:59

标签: c++ c++11

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

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

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

而不是

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

这是为了编译时执行没有代码或使其成为运行时的提示。 这可能吗?将所有这个typename设置为int?

2 个答案:

答案 0 :(得分:4)

快速解决方案是使用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;
}

答案 1 :(得分:2)

如果您想要一个接受int s参数包的模板,请自己设置一个模板:

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

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