我正在尝试构建一个设备,它将为一个值(特别是本机类型)做一件事,而对于一个C风格的基元数组则做另一件事。
这就是我现在所拥有的,这不符合我的意愿。
#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
template<class V> void dump_buf(const V& val)
{
cout << "val = " << val << "\n";
}
template<class A> void dump_buf(const A ary[])
{
cout << "ary size = " << sizeof(ary) << "\n";
for( size_t i = 0; i < sizeof(ary); ++i )
cout << "\t" << i+1 << " : " << ary[i] << "\n";
}
int main()
{
cout << "\n";
int i = 42;
float f = 3.14f;
unsigned fib[] = {0,1,1,2,3,5};
char s[] = "hello";
dump_buf(i);
dump_buf(f);
dump_buf(s);
dump_buf(fib);
}
这不起作用,因为ary
是指向某事物的类型,而不是某种数组。上面的输出(Intel,x64 compile,VS9)是:
val = 42
val = 3.14
ary size = 8
1 : h
2 : e
3 : l
4 : l
5 : o
6 :
7 : ╠
8 : ╠
ary size = 8
1 : 0
2 : 1
3 : 1
4 : 2
5 : 3
6 : 5
7 : 3435973836
8 : 3435973836
但我希望输出为:
val = 42
val = 3.14
ary size = 6
1 : h
2 : e
3 : l
4 : l
5 : o
6 :
ary size = 6
1 : 0
2 : 1
3 : 1
4 : 2
5 : 3
6 : 5
请注意,字符串的所需输出是6个字符而不是5个字符,因为null-terminator是数组的一部分。
有没有办法让它工作,只使用标准C ++而没有其他库?
几乎任何符合标准的技术都是可以接受的。重载,模板专业化,覆盖,类模板......一切都好。我对几乎任何可以实现我的目标的技术持开放态度。
答案 0 :(得分:3)
这应该可以解决问题:
template<class A, size_t S> void dump_buf(const A (& ary)[S])
{
cout << "ary size = " << S << "\n";
for( size_t i = 0; i < S; ++i )
cout << "\t" << i+1 << " : " << ary[i] << "\n";
}
通过引用数组而不是指向数组开头的指针,大小是已知的并且可用作推断的模板参数。
另外,请记住sizeof
给出了字节大小,所以当你想要一个数组中的对象数量(并且不能或不想使用这样的模板)时,你想要的sizeof(ary)/sizeof(*ary)
。在这两种情况下,你需要一个真正的数组,而不是一个指向数组的指针,它已经失去了对数组大小的所有了解。