为什么不能用模板数组引用?

_ZGq 2018-12-11 12:30:38
我写了这样一个函数:
template<typename T>
T max_r(T (&arr)[],int size,bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
//...
}

结果编译器报错了:
[Error] parameter 'arr' includes reference to array of unknown bound 'T []'

我想是T类型不确定,无法在编译期判断引用的大小的原因吧。
是这个原因吗?
如果是,要怎样改呢?(要求还是一个模板引用数组,如果C++不允许,为什么不允许呢?)如果不是这个原因,那是什么引起了这个错误呢?
...全文
318 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2018-12-12
  • 打赏
  • 举报
回复
引用 7 楼 weixin_41461277 的回复:
[quote=引用 6 楼 www_adintr_com 的回复:] 我说的引用需要指明数组的维度, 你这个不是引用的吗! 没有通过引用的时候, 数组参数是退化成指针的, T arr[] 等价于 T* arr
其实我是想说lambda表达式的问题。min_v函数也有这样的lambda表达式做函数指针,怎么没有警告或错误呢?(我开了[-Wall])[/quote] 额, 那可能是我的编译器不行把 但是你把这个参数类型定义成函数指针还是会限制用户可以使用的类型吧, 比如函数对象什么的.
srhouyu 2018-12-11
  • 打赏
  • 举报
回复
引用 7 楼 weixin_41461277 的回复:
[quote=引用 6 楼 www_adintr_com 的回复:] 我说的引用需要指明数组的维度, 你这个不是引用的吗! 没有通过引用的时候, 数组参数是退化成指针的, T arr[] 等价于 T* arr
其实我是想说lambda表达式的问题。min_v函数也有这样的lambda表达式做函数指针,怎么没有警告或错误呢?(我开了[-Wall])[/quote] lambda表达式本就可以隐式转换为函数指针,当然前提是你没有捕捉变量。你要是真写C++的话,还是建议你用std::function。
_ZGq 2018-12-11
  • 打赏
  • 举报
回复
引用 6 楼 www_adintr_com 的回复:
我说的引用需要指明数组的维度, 你这个不是引用的吗!
没有通过引用的时候, 数组参数是退化成指针的, T arr[] 等价于 T* arr

其实我是想说lambda表达式的问题。min_v函数也有这样的lambda表达式做函数指针,怎么没有警告或错误呢?(我开了[-Wall])
www_adintr_com 2018-12-11
  • 打赏
  • 举报
回复
引用 3 楼 weixin_41461277 的回复:
[quote=引用 1 楼 www_adintr_com 的回复:] 使用数组的引用你必须指明数组的维度, 如果要用于任意维度的, 可以再增加一个模板参数来表示维度. 还有, lambda 表达式是不能转换成一个函数指针类型的.
那为什么我上面写的
template<typename T>
T min_v(T arr[],int size,bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
	T min_value=arr[0];
	for(int i=1;i<size;++i){
		if(arr[i]>min_value) min_value=arr[i];
	}
	return min_value;
}
可以成立呢?编译器不会报错。 [/quote] 我说的引用需要指明数组的维度, 你这个不是引用的吗! 没有通过引用的时候, 数组参数是退化成指针的, T arr[] 等价于 T* arr
_ZGq 2018-12-11
  • 打赏
  • 举报
回复
我意识到一个问题:我没有把compare_func_if_x_less_than_y用上,改了一下,结果如下:
template<typename T,int size>
T& max_r(T (&arr)[size],bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
T max_value=arr[0],max_number=0;
for(int i=1;i<size;++i){
if(compare_func_is_x_less_than_y(max_value,arr[i])) max_value=arr[i],max_number=i;
}
return arr[max_number];
}
_ZGq 2018-12-11
  • 打赏
  • 举报
回复
template<typename T,int size>
T& max_r(T (&arr)[size],bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){ //刚才代码中少了一个&,补上
T max_value=arr[0],max_number=0;
for(int i=1;i<size;++i){
if(arr[i]>max_value) max_value=arr[i],max_number=i;
}
return arr[max_number];
}
_ZGq 2018-12-11
  • 打赏
  • 举报
回复
引用 1 楼 www_adintr_com 的回复:
使用数组的引用你必须指明数组的维度, 如果要用于任意维度的, 可以再增加一个模板参数来表示维度.
还有, lambda 表达式是不能转换成一个函数指针类型的.

那为什么我上面写的
template<typename T>
T min_v(T arr[],int size,bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
T min_value=arr[0];
for(int i=1;i<size;++i){
if(arr[i]>min_value) min_value=arr[i];
}
return min_value;
}
可以成立呢?编译器不会报错。



引用 2 楼 srhouyu 的回复:
这跟模板没关系。

数组的引用要求很严格,形参和实参得长度一样,例如你定义float max(float (&arr)[100])的话,就得传入一个float arr[100],传入float arr[101]都不行。所以编译器根本不会接受你这种不定长数组的无理要求。建议你把size写在模板参数中,这样才是定长的。只不过这样每一个不同的size都是一个不同的函数版本。

正确姿势:

template<typename T, int SIZE>
T max_r(T (&arr)[SIZE],bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
//...
}

我根据实际需要稍微修改了一下,也测试通过了:
template<typename T,int size>
T max_r(T (&arr)[size],bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
T max_value=arr[0],max_number=0;
for(int i=1;i<size;++i){
if(arr[i]>max_value) max_value=arr[i],max_number=i;
}
return arr[max_number];
}
谢谢
srhouyu 2018-12-11
  • 打赏
  • 举报
回复
这跟模板没关系。 数组的引用要求很严格,形参和实参得长度一样,例如你定义float max(float (&arr)[100])的话,就得传入一个float arr[100],传入float arr[101]都不行。所以编译器根本不会接受你这种不定长数组的无理要求。建议你把size写在模板参数中,这样才是定长的。只不过这样每一个不同的size都是一个不同的函数版本。 正确姿势:

template<typename T, int SIZE>
T max_r(T (&arr)[SIZE],bool(*compare_func_if_x_less_than_y)(T,T)=[](T x,T y)->bool{return x<y;}){
    //...
}
www_adintr_com 2018-12-11
  • 打赏
  • 举报
回复
使用数组的引用你必须指明数组的维度, 如果要用于任意维度的, 可以再增加一个模板参数来表示维度. 还有, lambda 表达式是不能转换成一个函数指针类型的.

#include <stdio.h>
#include <algorithm>

template<typename T, int N, typename Pred = std::less<T> >
T max_r(T (&arr)[N], Pred pred = std::less<T>())
{
	T max = arr[0];

	for (int i = 1; i < N; ++i)
	{
		if (pred(max, arr[i]))
		{
			max = arr[i];
		}
	}

	return max;
}

int main(int argc, char **argv)
{
	int a[] = { 1, 2, 3, 10, 4, 5 };
	
	printf("%d\n", max_r(a));
}

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧