[c&cpp]const char* 和const char []在代码中如何识别各自类型
这是德问技术社区的一个问题,测试了一下,使用typeid等方法都无法正确区分二者,不讨论二者是不是有必要进行区分;
下面给出一个方案吧,其实就是利用了Traits,模板的匹配规则。
1: template<typename T> class _ischararray_;
2:
3: template<typename T, int N>
4: class _ischararray_<T[N]> { public: static bool _ischararray(){return true;}};
5:
6: template<typename T>
7: class _ischararray_<T*> { public: static bool _ischararray(){return false;}};
8:
9: template<class T>
10: bool isCharArray(const T& x) { return _ischararray_<T>::_ischararray();}
测试代码:
1: const char* s1 = "12345";
2: const char s2[] = "12345";
3: isCharArray("12345")?cout<<"char []"<<endl:cout<<"char*"<<endl; //char []
4: isCharArray(s1)?cout<<"char []"<<endl:cout<<"char*"<<endl; //char*
5: isCharArray(s2)?cout<<"char []"<<endl:cout<<"char*"<<endl; //char []
注解:
字符串直接量"12345"输出为char []的原因:字符串常量的类型应该理解为相应字符常量数组的类型,这一点,从sizeof运算符上可以看出来,sizeof得到的是类型大小信息,sizeof("12345"),得到的大小是6而不是4,因为其类型为const char[6],如果类型是char*,sizeof的结果应该是4,更多一点的内容可以看一下:
[cpp] 字符数组,字符指针,sizeof,strlen总结
+ 2010/3/15,更新一种更好的方式. 在SO上发布了这个问题,和iammilind交互得到一个更好的方式:
In namespace Y, a compile time solution,it doesn't need any execution cycles.
namespace X
{
template<typename T, unsigned int SIZE>
bool IsArray (T (&a)[SIZE]) { return true; }
template<typename T>
bool IsArray (const T *&p) { return false; }
}
namespace Y
{
typedef char (&yes)[2];
template<typename T, unsigned int SIZE>
yes IsArray (T (&a)[SIZE]);
template<typename T>
char IsArray (const T *&p);
}
int main ()
{
char s1[] = "hello";
const char *s2 = "hello";
#if 1
using namespace X;
if(true == IsArray(s2))
throw 0;
if(false == IsArray("12345"))
throw 0;
if(false == IsArray(s1))
throw 0;
#else
using namespace Y;
if(sizeof(IsArray(s2)) == sizeof(yes))
throw 0;
if(sizeof(IsArray(s1)) != sizeof(yes))
throw 0;
#endif
}