- #include <string>
- // 注意:使用 reference parameters
- template <typename T>
- inline T const& max (T const& a, T const& b)
- {
- return a < b ? b : a;
- }
- int main()
- {
- std::string s;
- ::max("apple","peach"); // OK:类型相同
- ::max("apple","tomato"); // ERROR:类型不同
- ::max("apple",s); // ERROR:类型不同
- return 0;
- }
上面的代码是C++ template 5.6中的程序,David详细的解释了为什么会这样的原因:
问题出在这几个字符串字面常数(string literals)的长度不同,因而其底层的 array 类型也不
同。
换句话说 "apple" 和 "peach" 的 array 类型都是 char const[6],而 "tomato" 的 array
型 别是 char const[7]。上述调用只有第一个合法,因为两个参数具有相同类型;然而如果你
使
用 by value 传递方式,就可以传递不同类型的字符串字面常数(string literals),其对应的 array
大小不同:
- // basics/max6.hpp
- #include <string>
- // 注意:使用 non-reference parameters
- template <typename T>
- inline T max(T a, T b)
- {
- return a < b ? b : a;
- }
- int main()
- {
- std::string s;
- ::max("apple","peach"); // OK:类型相同
- ::max("apple","tomato"); // OK:退化为相同类型
- ::max("apple",s); // 错误:类型不同
- }
这种方式之所以可行,因为在自变量推导过程中,惟有当参数并不是一个 reference 类型时,「array
转为 pointer」的转型动作(常被称为退化, decay)才会发生。这个规则可藉以下例子加以说明:
- // basics/refnonref.cpp
- #include <typeinfo>
- #include <iostream>
- template <typename T>
- void ref (T const& x)
- {
- std::cout << "x in ref(T const&): "
- << typeid(x).name() << std::endl;
- }
- template <typename T>
- void nonref (T x)
- {
- std::cout << "x in nonref(T): "
- << typeid(x).name() << std::endl;
- }
- int main()
- {
- ref("hello");
- nonref("hello");
- }
详细见C++ template the complete guide