// print any type we don't otherwise handle template <typename T> string debug_rep(const T &t) { cout << "debug_rep(T const&)\n"; ostringstream ret; // see § 8.3 (p. 321) ret << t; // uses T's output operator to print a representation of t return ret.str(); // return a copy of the string to which ret is bound } // print pointers as their pointer value, followed by the object to which the pointer points // NB: this function will not work properly with char*; see § 16.3 (p. 698) template <typename T> string debug_rep(T *p) { std::cout << "debug_rep(T*)\n"; ostringstream ret; ret << "pointer: " << p << '\n'; // print the pointer's own value if (p) ret << " " << debug_rep(*p); // print the value to which p points else ret << " null pointer"; // or indicate that the p is null return ret.str(); // return a copy of the string to which ret is bound }
If we call debug_rep with a pointer:
cout << debug_rep(&s) << endl;
both functions generate viable instantiations:
debug_rep(const string* &)
, which is the instantiation of the first version of debug_rep withT
bound tostring*
debug_rep(string*)
, which is the instantiation of the second version ofdebug_rep
withT
bound tostring*
The instantiation of the second version of
debug_rep
is an exact match for this call.The instantiation of the first version requires a conversion of the plain pointer to a pointer to
const
. Normal function matching says we should prefer the second template, and indeed that is the one that is run.
但是,如果我将指向字符串的指针声明为const
,即使没有转换,第二个版本也总是被选择:
string const s("hi"); // const
cout << debug_rep(&s) << '\n';
我认为书中存在一个错误,并且我认为因为版本采用指针是首选,因为我们可以传递一个const
或非const
的指针(T
将被推导为std::string const*
或std::string*
)。
您怎么看?