This is a question of the German technical community. After testing, neither of the methods such as typeid can be used to distinguish the two. We do not discuss whether it is necessary to distinguish them;
The following is a solution. In fact, traits is used to match the template rules.
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();}
Test code:
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 []
Note:
The reason why "12345" is output as char []: the type of the String constant should be understood as the type of the corresponding String constant array. This can be seen from the sizeof operator, sizeof gets the type size information, sizeof ("12345"), and the size is 6 instead of 4, because the type is const char [6], if the type is char *, the result of sizeof should be 4. For more information, see:
[CPP] character array, character pointer, sizeof, strlen Summary
Code on ideone
+ 2010/3/15, a better way is provided. This issue is released on so, and a better way to interact with iammilind is obtained:
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