我有這樣的模板函數:非模板類型參數
template<int i> void f(int a[i]) { };
int main() {
int c[10];
f(c); // Causes an error!
}
爲什麼不能我通過c[10]
作爲非模板類型參數模板功能?
我有這樣的模板函數:非模板類型參數
template<int i> void f(int a[i]) { };
int main() {
int c[10];
f(c); // Causes an error!
}
爲什麼不能我通過c[10]
作爲非模板類型參數模板功能?
記住,看起來像一個數組的函數參數實際上是一個指針,所以你的模板實際上是等同於
template<int i> void f(int * a);
沒有辦法推斷出函數參數模板參數。你可以明確地指定它:
f<10>(c);
但這很容易出錯;一個更好的選擇是通過參考數組傳遞,從而使模板參數可推導出:
template<int i> void f(int (&a)[i]);
替代地,在C++ 11或更高,則可以使用std::array
這是一個合理的對象類型與無的內置數組類型的怪癖。
的原型應該是:
template<std::size_t N> void f(int (&a)[N]) { };
注意(&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) { };
不幸的是陣列有效地失去它們的大小信息,當您通過他們,所以編譯器不能從您的通話推斷的i
值。一個頗爲不雅的解決辦法是顯式地指定模板參數在您的呼叫,例如:
f<10>(c);
顯然是非常失敗,雖然具有模板的點。更好的選擇可能是使用std::array
。
其實正確的函數模板將使用std::size_t
作爲模板參數:
template<std::size_t i> void f(int (&a)[i])
但使用std::array
可能是更好:
template<std::size_t i> void f(const std::array<int, i>&)
你也應該考慮使用迭代,如果算法您正在開發的f
應該與任何提供迭代器的容器一起工作:
template<class It> void f(It begin, It end)
,讓您可以使用您的功能如下:
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));
後者通常使用的STL庫的容器無關的算法。
你可以,只是參數'int a [i]'衰變成指針,實際上失去了它的大小信息。因此,當您調用該函數時,「i」不會被推導出來。如果你像'f <10>(c)'那樣調用這個函數,它就會起作用。 – 0x499602D2