我们都知道,对于void doSomething(char buf[])而言,buf只是一个char*,对其求sizeof无法获得buf缓冲大小,有时候,尤其是需要验证缓冲是否大小合法的时候,获取数组完整信息是十分有必要的,而这要求sizeof获得的buf是直接的buf[]而不是char*,在我所知道的情况里,如果不用模板,我们总是传递的一个指针,而使用模板的时候,只有传递引用才可以获得正确的数组信息,为此我做了一个测试例子:
void
testa(
char
*
buf)
... {
cout<<"char pointer:"<<sizeof(buf)<<endl;
}
// void testb(char*& buf)
// {
// cout<<"char pointer reference:"<<sizeof(buf)<<endl;
// }
void testc( char buf[])
... {
cout<<"char array:"<<sizeof(buf)<<endl;
}
// compile error
// void testd(char& buf[])
// {
// cout<<"char array reference:"<<sizeof(buf)<<endl;
// }
// void teste(char[] buf)
// {
// cout<<"array:"<<sizeof(buf)<<endl;
// }
//
// void testf(char[]& buf)
// {
// cout<<"array reference:"<<sizeof(buf)<<endl;
// }
template < class T >
void testg(T buf)
... {
cout<<"template:"<<sizeof(buf)<<endl;
}
template < class T >
void testh(T & buf)
... {
cout<<"template reference:"<<sizeof(buf)<<endl;
}
int _tmain( int argc, _TCHAR * argv[])
... {
char t[100];
testa(t);
//testb(t);
testc(t);
//testd(t);
//teste(t);
//testf(t);
testg(t);
testh(t);
return 0;
}
... {
cout<<"char pointer:"<<sizeof(buf)<<endl;
}
// void testb(char*& buf)
// {
// cout<<"char pointer reference:"<<sizeof(buf)<<endl;
// }
void testc( char buf[])
... {
cout<<"char array:"<<sizeof(buf)<<endl;
}
// compile error
// void testd(char& buf[])
// {
// cout<<"char array reference:"<<sizeof(buf)<<endl;
// }
// void teste(char[] buf)
// {
// cout<<"array:"<<sizeof(buf)<<endl;
// }
//
// void testf(char[]& buf)
// {
// cout<<"array reference:"<<sizeof(buf)<<endl;
// }
template < class T >
void testg(T buf)
... {
cout<<"template:"<<sizeof(buf)<<endl;
}
template < class T >
void testh(T & buf)
... {
cout<<"template reference:"<<sizeof(buf)<<endl;
}
int _tmain( int argc, _TCHAR * argv[])
... {
char t[100];
testa(t);
//testb(t);
testc(t);
//testd(t);
//teste(t);
//testf(t);
testg(t);
testh(t);
return 0;
}
注释掉的部分是无法编译通过的,最后的运行结果是:
char
pointer:
4
char array: 4
template: 4
template reference: 100
char array: 4
template: 4
template reference: 100
可以看到,确实只有template和reference的使用得到了我们想要的数据,而且,通过输出的数据我们可以看到,buf[]事实上在编译阶段也被认为是char*(testg),我们可以获取它的完整信息是因为使用引用模式时类型是完整的数据定义时候的样子,为了说明这个问题,我做如下修改:
template
<
class
T
>
struct NonExistStruct;
template < class T >
void testg(T buf)
... {
NonExistStruct<T>();
cout<<"template:"<<sizeof(buf)<<endl;
}
template < class T >
void testh(T & buf)
... {
NonExistStruct<T>();
cout<<"template reference:"<<sizeof(buf)<<endl;
struct NonExistStruct;
template < class T >
void testg(T buf)
... {
NonExistStruct<T>();
cout<<"template:"<<sizeof(buf)<<endl;
}
template < class T >
void testh(T & buf)
... {
NonExistStruct<T>();
cout<<"template reference:"<<sizeof(buf)<<endl;
涉及了两个模板方法,为了获取编译器替换阶段的信息,我故意定义了不存在的东西让编译器报错,得到的错误信息是:
//
前者
error C2514: ' NonExistStruct<T> ' : class has no constructors
1 > with
1 > [
1 > T = char *
1 > ]
// 后者
error C2514: ' NonExistStruct<T> ' : class has no constructors
1 > with
1 > [
1 > T = char [ 100 ]
1 > ]
error C2514: ' NonExistStruct<T> ' : class has no constructors
1 > with
1 > [
1 > T = char *
1 > ]
// 后者
error C2514: ' NonExistStruct<T> ' : class has no constructors
1 > with
1 > [
1 > T = char [ 100 ]
1 > ]
这太形象了,只有在使用模板引用的时候,被传递了数组的原本模样。