当我想将可变参数模板参数包分成两部分时,我遇到了这个问题,第一部分包含所有元素但最后一部分,第二部分只包含最后一部分。我想到的一个直接实现是以下示例中的invoke1
函数:
template <typename... Ts>
void invoke1(Ts... ts, int param) {
}
template <typename... Ts>
void invoke2(int param, Ts... ts) {
}
int main() {
invoke1(1); // this works
invoke2(1); // this works
invoke1(1, 2, 3); // this does not work
invoke1<int, int>(1, 2, 3); // this works
invoke2(1, 2, 3); // this works
return 0;
}
为什么在首先指定模板参数包时,不会推导invoke1
的模板参数?它会在类型演绎中产生歧义吗?
答案 0 :(得分:2)
template <typename... Ts>
void invoke1(Ts... ts, int param) {
}
首先,为什么
invoke1<int, int>(1, 2, 3);
工作?以上明确指定了类型,因此不需要类型推导。模板实例化为:
void invoke1(int, int, int);
所以(1, 2, 3)
的通话现在变得非常有效。
另一方面,如果您没有明确指定类型,编译器无法知道参数包的结束位置。
是invoke1(int, int, int, int);
还是invoke1(int, int, int);
?
现在,您要说:&#34;它不能只取最后一个给定的参数并在它之前结束参数包吗?&#34;。好吧,答案是没有。
另一方面, invoke2
工作正常,因为它清楚参数包的开始和结束位置。
根据经验,始终将参数包放在最后。