如果我有int x[10]
和int *y
,我怎么能区分这两者?
我有两个想法:
sizeof()不同。
- 醇>
& x有不同的类型---
int (*p)[10] = &x
有效,但不是int **q = &x
。
还有其他人吗?
在某些模板库代码中,我需要确定指针是“实际”指针还是从数组中退化。我不能查看源代码,因为在我编写库之前库用户不存在。 ...我可以通过重写代码解决这个问题,所以现在这只是一个理论上的练习。
答案 0 :(得分:5)
没有通用方法 - 您已经知道了类型,因为您刚刚声明了对象,或者类型已经衰减到指针并且已经丢失。请通过区分它们来解释您试图解决的问题。
答案 1 :(得分:2)
sizeof
的想法不是很好,因为如果数组恰好有一个元素,并且元素类型碰巧与指针大小相同,那么它的大小将与大小相同指针。
类型匹配方法看起来更有前景,并且可能被用于选择模板专业化(如果这就是你要做的)。
答案 2 :(得分:2)
假设您没有尝试为在函数范围声明的类型执行此操作:
struct yes { char pad; };
struct no { yes pad[2]; };
template <typename T, size_t N> yes is_array_test(T (&arr)[N]);
no is_array_test(...);
#define IS_ARRAY(x) (sizeof(is_array_test(x))==sizeof(yes))
答案 3 :(得分:0)
int x [10]将在它被调用的地方总是分配在堆栈上。 x值永远不会改变。
int * y只是声明一个指向内存的指针,指针值可以随时更改而不受任何限制。
int * y可以有任意值。意思是,它可以指向堆栈分配的Memoryor堆分配的内存。从技术上讲,它也可以指向无效的内存,但这没有任何意义。
int x [10] guarntee你总是指向一个有效的内存,你不必担心内存释放。
使用int * y时,你必须担心它所指向的内存。
另外请记住,你的porgram动态分配内存的次数越多,它就会暴露于错误,泄漏,性能问题,分配\解除分配和许多其他类型的问题。
答案 4 :(得分:0)
它们是不同的类型。
你如何区分int32和uint32,或者uint32和char [4]?
正确的思考方式是它们相似的唯一方法是在某些上下文(包括数组索引!)中,数组会提升为指针。
答案 5 :(得分:0)
我刚尝试使用g ++ 4.5 C ++ 0x模式中的char数组,它不会让我同时定义
template <typename T>void moresilly(const T v[],const char *description)
AND
template <typename T>void moresilly(const T *v,const char *description)
它声称两者都是同一类型。
我有一个功能:
template <typename T>void silly(const T & v,const char *description)
{
cout<<"size of "<<description<<" is "<< sizeof(T)<<endl;
moresilly(v,description);
}
如果传递正确获取数组的大小,如果传递则正确获取指针的大小,但我不能使用moresilly来区分指针和数组,所以我不能告诉4字符数组从指针到n个字符。
在T [1],T [2],T [3]等上有模板可能有用,但是已经有帖子说不同的编译器处理那个(或类似的情况)不同而且gnu更喜欢C ++ 11中的指针匹配。
......稍后补充: 经过一些实验,我发现了一些适用于g ++ 4.5的东西
template <typename T,size_t L>void moresilly(const T (&v)[L],const char *description)
{
cout<<description<<" is an array"<<endl;
}
template <typename T>void moresilly(const T *v,const char *description)
{
cout<<description<<" is a pointer"<<endl;
}
template <typename T>void moresilly(const T v,const char *description)
{
cout<<description<<" is a raw value"<<endl;
}
template <typename T>void silly(const T & v,const char *description)
{
cout<<"size of "<<description<<" is "<< sizeof(T)<<endl;
moresilly(v,description);
}
以下工作正常
silly("12345","immediate string of 5 characters plus zero");
silly((const char *)"12345","immediate constant char pointer of 5 characters plus zero");
char testarray[]="abcdef";
silly(testarray,"char array of 6 characters plus zero");
const char testarray2[]="abcdefg";
silly(testarray2,"const char array of 7 characters plus zero");
请注意,如果第一个函数定义为“const T v [L]”而不是“const T(&amp; v)[L]”,则它不起作用,从不匹配任何内容。
所以我解决了你的问题,但是不要指望这个在其他版本的编译器中工作,包括未来的版本。这就是我讨厌c ++的原因。不知何故,语言的定义是如此不清楚,编译器充满了不稳定的边缘情况。
这是一个有用的技巧,我可以使用它。