[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总结

Code On ideone

 

+ 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
}

Code On ideone

你可能感兴趣的:(Const)