目的是:定义一个比较函数compare
为了满足通用类型的比较,建立函数模板如下:
template <typename T> int compare(const T &v1, const T &v2) { if (v1 < v2)return -1; if (v1>v2)return 1; return 0; }
这个T可以满足int,string,vector<int>,vector<string>各种通用类型,甚至自定义类型的两个对象的比较
对于compare("123","1234")这样的比较,这个函数模板就不满足了。因为在C++中,字符串字面常量是const char的数组,比如"123"实质类型是 const char[4],"1234"实质类型是const char[5],之所以数组长度多1,是由于编译器会在字符串字面常量的末尾插入一个空字符作为终结符。
这样的话,compare函数的两个参数的类型其实分别是const char[4]和const char[5],所以上面的那个函数模板不满足要求。于是,针对字符串常量再创建另一个函数模版如下:
template <unsigned N, unsigned M> int compare(const char(&p1)[N], const char(&p2)[M]) { return strcmp(p1, p2); }
这样就满足了compare("123","1234")的运行要求,其中数组使用引用的原因是数组不可以拷贝。
当然在这一步,本以为执行compare("123","456")也没问题(也就是两个字符串常量的长度是一样的),可是这里就出现让我觉得难理解的问题了:出现编译时错误。
提示有多个重载函数的实例与参数列表匹配。如下:
意思是没有找到最佳匹配,或者说这两个函数模板对于compare("123","456")的匹配优先级是一致的。如果将这两个函数模板去掉任意一个,则compare("123","456")均可以编译通过(当然,这里先不论真实逻辑)。但是这样处理的话,compare函数的通用性就失去了,另外,这两个函数模板各有各自要处理的比较类型,都不能失去。
于是,再增加一个函数模板,这个模板类似template <unsigned N, unsigned M> ,不同的是将非类型参数从两个改成一个(去掉了M):
template <unsigned N, unsigned N> int compare(const char(&p1)[N], const char(&p2)[N]) { return strcmp(p1, p2); }
这种情况下,针对compare("123","456")这种两个字符串常量参数的长度一致的情况,编译器会选择这个新的函数模板作为最佳匹配进行处理。
我是这么理解的,但是感觉这种处理很反逻辑啊。