向具有可变模板的函数传递对数组的可变引用数
Passing a variable number of references-to-arrays to a function with variadic templates
我知道如何编写一个接受可变数量参数的可变模板函数:
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…)[其中T=int,unsigned int Length=3u,Rest={int*,int*}]'
a.cpp:23:22:从这里实例化
a.cpp:17:27:错误:没有用于调用"f(int*&,int*&aamp;)"的匹配函数
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个
然而,除了修复第二个代码(这更像是一种解决方法,因为我不知道如何做我真正想做的事情),这个问题的实际意义和我真正想学习的东西是如何在不使用代理对象的情况下做到这一点,如果可能的话,就像第一个代码一样。那么如何做到这一点呢?在我发布的一个尝试中,是否只是一个简单的语法错误?
如果你只想求出一些数组的长度,你可以直接这样做:
template<typename T, unsigned int Length>
int f(const T (&)[Length]) {
return Length;
}
template<typename T, unsigned int Length, typename... Args>
int f(const T (&)[Length], Args&... rest) {
return Length + f(rest...);
}
int main() {
int a[] = { 1, 2, 3 }, b[] = { 1, 2, 3, 4, 5 }, c[] = { 1 };
std::cout << f(a, b, c);
}
您可以使用std::extent
来获取数组外部维度的范围,并对这些范围进行方差求和:
#include <type_trait>
template <typename Arr, typename ...Rest> struct extent_sum
: std::integral_constant<std::size_t,
std::extent<T>::value + extent_sum<Rest...>::value> { };
template <typename T> struct extent_sum<T>
: std::integral_constant<std::size_t, std::extent<T>::value> { };
用法:
const std::size_t n = extent_sum<int[2], char[4], float[3], bool>::value;
- 通过指针与数组引用扩展数组索引序列
- 将链表的内容放在数组引用中
- 是否允许使用初始值设定项列表将const数组引用实例化为构造函数参数
- C 在将数组引用分配给struct时麻烦
- Typedef数组引用
- 通过强制转换创建子数组引用
- 将数组引用 'T(&)[n]' 引用到 'std::array<T, n>' 的内容
- constexpr 数组引用参数
- 寻找有关函数定义和原型中数组引用的说明
- Initializer_list作为非模板上下文中数组引用参数的参数
- 如何使用一个动态创建的一维数组的二维数组引用仅与标准库?
- 如何返回具有大小的POD数组引用
- 在C++中返回数组引用的语法
- 是否可以声明转换函数返回数组引用而不使用typedef
- 自定义到数组引用的转换
- 类数组引用的NullReferenceException
- 数组指针与数组引用之间的差异
- 在c++中传递数组引用
- 使用特征矩阵作为特征数组引用的参数
- 如何从函数传递数组引用