非模板类型参数

Vis*_*iva 4 c++ templates

我有这个模板功能:

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]作为非模板类​​型参数传递给模板函数?

Mik*_*our 7

请记住,看起来像数组的函数参数实际上是指针,因此您的模板实际上等效于

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哪个是合理的对象类型,没有内置数组类型的怪癖.


Sho*_*hoe 6

实际上,正确的函数模板将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库用于其与容器无关的算法.


Jar*_*d42 5

原型应该是:

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)