我有这个模板功能:
template<int i> void f(int a[i]) { };
int main () {
int c[10];
f(c); // Causes an error!
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能c[10]作为非模板类型参数传递给模板函数?
请记住,看起来像数组的函数参数实际上是指针,因此您的模板实际上等效于
template<int i> void f(int * a);
Run Code Online (Sandbox Code Playgroud)
无法从函数参数中推断出模板参数.您可以明确指定它:
f<10>(c);
Run Code Online (Sandbox Code Playgroud)
但这很容易出错; 更好的选择是通过引用传递数组,以便可以推导出模板参数:
template<int i> void f(int (&a)[i]);
Run Code Online (Sandbox Code Playgroud)
或者,在C++ 11或更高版本中,您可以使用std::array哪个是合理的对象类型,没有内置数组类型的怪癖.
实际上,正确的函数模板将std::size_t用作模板参数:
template<std::size_t i> void f(int (&a)[i])
Run Code Online (Sandbox Code Playgroud)
但使用a std::array可能更好:
template<std::size_t i> void f(const std::array<int, i>&)
Run Code Online (Sandbox Code Playgroud)
如果您正在开发的算法应该与任何提供迭代器的容器一起使用,您还应该考虑使用迭代f器:
template<class It> void f(It begin, It end)
Run Code Online (Sandbox Code Playgroud)
这样你就可以像这样使用你的功能了:
int x[10] = ...;
std::vector<int> y = ...;
std::array<int, 10> z = ...;
f(std::begin(x), std::end(x));
f(std::begin(y), std::end(y));
f(std::begin(z), std::end(z));
Run Code Online (Sandbox Code Playgroud)
后者通常由STL库用于其与容器无关的算法.
原型应该是:
template<std::size_t N> void f(int (&a)[N]) { };
Run Code Online (Sandbox Code Playgroud)
请注意(&a)语法.
void f(int a[N])衰败void f(int* a),我们不能推断模板N.
std::array 语法看起来更好:
template<std::size_t N> void f(std::array<int, N>& a) { };
Run Code Online (Sandbox Code Playgroud)