非最后一个参数包编译错误

Non-last parameter pack compilation error

我想了解当参数包不是最后一个参数时,它们在可变参数模板函数中是如何工作的。我不明白为什么我的示例代码中的某些调用不起作用。问题在评论中。它们应该工作还是我不明白某些东西或者 VS2015 update 3 的编译器还不支持它们?

template <typename T>
double sum(T t) {
    return t;
}

template <typename T, typename... Rest>
double sum(Rest... rest, T t) {
    return t + sum(rest...);
}

template <typename T>
double sum2(T t) {
    return t;
}

template <typename T, typename... Rest>
double sum2(T t, Rest... rest) {
    return t + sum2(rest...);
}

template<typename... Args>
void func(Args..., int = 0)
{}

void func()
{
    func<int, int, int>(1, 1, 1);
    func(1, 1, 1); // why doesn't this compile?
    sum(1, 1); // why doesn't this compile?
    sum<int, int>(1, 1);
    sum<int, int, int>(1, 1, 1); // why doesn't this compile while func<int, int, int>(1, 1, 1) does?

    // why are these compile? I only changed the order of the parameters compared to sum()
    sum2(1);
    sum2(1, 1);
    sum2(1, 1, 1);
}

我不是专家,但据我所知...

func(1, 1, 1); // why doesn't this compile?

因为在函数模板中,参数包的类型只有在最后一个位置才能推导出来。

第一次通话

func<int, int, int>(1, 1, 1);

之所以有效,是因为参数的类型没有被推导出来,而是被解释了(Args...int, int, int)并且 func() 收到第四个 int(具有默认值零)

来电

func<int, int>(1, 1, 1);

也有效,因为 Args... 被解释为 int, int 并且 func() 函数接收到第三个 int 而不是默认值 1


sum(1, 1); // why doesn't this compile?

同理:参数包不在最后位置,无法推导;但有效

sum<int, int>(1, 1);

因为 T 被解释为 intRest... 也被解释为 int


sum<int, int, int>(1, 1, 1); // why doesn't this compile while func<int, int, int>(1, 1, 1) does?

拳头级别调用有效,因为 T 被解释为 intRest... 被解释为 int, int;但是 sum<int, int, int>(1, 1, 1) 调用 sum(rest...),在这种情况下是 sum(1, 1);失败的是 sum(1, 1),因为 Rest... 不在最后位置,因此无法推导出


// why are these compile? I only changed the order of the parameters compared to sum()
sum2(1);
sum2(1, 1);
sum2(1, 1, 1);

因为在sum2()中参数包列表Rest...在最后一个位置所以可以(并且是)推导。