让我们考虑下面的两个代码;
以下代码对模板参数中给出的所有数字求和,其中函数的签名是等价的;如果你取消注释 template <class T, T v1> T sum1()
部分,那么你会得到一个编译错误。
#include <iostream>
template <class T> T sum1() { return T{0}; }
// template <class T, T v1> T sum1() { return v1; } // Ambiguous!
template <class T, T v1, T... v2> T sum1() {
return v1 + sum1<T, v2...>();
}
int main(void) {
std::cout << sum1<int, 1>() << '\n';
std::cout << sum1<int, 1, 2>() << '\n';
std::cout << sum1<int, 1, 2, 3>() << '\n';
}
以下代码打印函数签名中给出的所有参数,其中具有可变参数模板的参数具有附加的省略号参数;没有编译器错误发生。
#include <iostream>
template <class T> void print(std::ostream &out, T value) {
out << value << std::endl;
}
template <class T, class... Types> void print(std::ostream &out, T value, Types... values) {
out << value << ' ';
print(out, values...);
}
int main(void) {
print(std::cout, 1, 2.3, "abc");
}
到目前为止,我的理解是,如果您取消注释 template <class T, T v1>
部分,那么编译器将对 <class T, T v1>
部分进行实例化,但是 <class T, T v1, T... v2>
将尝试生成 <class T, T v1>
的另一个实例化,因此它失败了。
但是,似乎同样的事情不适用于 print
功能。这是因为额外的省略号参数 values
?
供您参考,我使用 g++ 7.5 和 --std=c++17
和 -g
。