【发布时间】:2012-02-10 17:55:31
【问题描述】:
我知道如何编写一个接受可变数量参数的可变参数模板函数:
template<int I, typename... Rest>
void f() {
// whatever
}
而且我知道如何编写一个接受数组引用的模板函数:
template<typename T, unsigned int Length>
void f(T(&arr)[Length]) {
// whatever
}
但我想不出如何将两者结合起来,以便函数接受可变数量的数组引用。
我的第一次尝试是
template<typename T, unsigned int Length>
unsigned int arrlen(T(&)[Length]) {
return Length;
}
template<typename T, unsigned int Length>
int f(T(&arr)[Length]) {
return Length;
}
template<typename T, unsigned int Length, typename... Rest>
int f(T(&arr)[Length], Rest... rest) {
return Length + f(rest...);
}
int main() {
int a[] = {1 , 2, 3}, b[] = {1, 2, 3, 4, 5}, c[] = {1};
cout << f(a, b, c);
}
但是编译器告诉我
a.cpp: 在函数'int f(T (&)[Length], Rest ...) [with T = int, unsigned int Length = 3u, Rest = {int*, int*}]'
a.cpp:23:22: 从这里实例化
a.cpp:17:27: 错误:没有匹配函数调用 'f(int*&, int*&)'
a.cpp:17:27:注意:候选人是:
a.cpp:11:22: 注意:模板 int f(T(&)[Length])
a.cpp:16:5: 注意:模板 int f(T(&)[Length], Rest ...)
所以我在想你可以编写一个对象来存储构造它的数组的长度,然后将其中的可变数量(将从传递的数组隐式构造)传递给函数。这是我的尝试:
template<typename T, unsigned int Length>
struct Array {
Array(T(&arr)[Length]) : arr(arr), len(Length) { }
T(&arr)[Length];
const unsigned int len;
};
int f() {
return 0;
}
template<typename T, unsigned int Length, typename... Args>
int f(const Array<T, Length>& a1, Args... rest) {
return a1.len + f(rest...);
}
int main() {
int a[] = { 1, 2, 3 }, b[] = { 1, 2, 3, 4, 5 }, c[] = { 1 };
cout << f(a, b, c);
}
但是当我尝试用 GCC 4.6.1 编译它时,我得到了错误
a.cpp:在函数'int main()'中:
a.cpp:27:22: 错误:没有匹配函数调用 'f(int [3], int [5], int [1])'
a.cpp:27:22:注意:候选人是:
a.cpp:16:47: 注意:模板 int f(const Array&, Args ...)
a.cpp:20:5: 注意:int f()
a.cpp:20:5:注意:候选人需要 0 个参数,提供 3 个
但是,除了修复第二个代码(这更像是不知道如何做我真正想做的事情的解决方法)之外,这个问题的实际意义和我真正想学习的事情是如何做如果可能的话,不使用这样的代理对象,就像第一个代码一样。那么如何做到这一点呢?我发布的其中一个尝试中是否只有一个简单的语法错误?
【问题讨论】:
-
只需使用
std::array并忘记原始数组的废话。 -
@CatPlusPlus 这将是一个简单的方法,不会帮助我了解这里发生了什么。
-
@CatPlusPlus 实际上会出现同样的问题
-
不,不会。
std::array不会衰减为指针,因此您不必使用作为模板参数传递的大小。 -
@CatPlusPlus 啊你是对的,我忘了问题是由数组到指针衰减引起的
标签: c++ templates c++11 variadic-templates