【发布时间】:2020-12-10 21:29:54
【问题描述】:
C++ Primer一书中,有一个关于函数模板重载的例子:
// 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 }如果我们用指针调用 debug_rep:
cout << debug_rep(&s) << endl;这两个函数都会生成可行的实例化:
debug_rep(const string* &),这是第一个版本的 debug_rep 的实例化,T绑定到string*
debug_rep(string*),这是debug_rep的第二个版本的实例化,T绑定到string*
debug_rep的第二个版本的实例化与此调用完全匹配。第一个版本的实例化需要将普通指针转换为指向
const的指针。正常函数匹配表明我们应该更喜欢第二个模板,而且确实是运行的那个。
但是,如果我将指向字符串的指针声明为 const 尽管没有转换,则始终选择第二个版本:
string const s("hi"); // const
cout << debug_rep(&s) << '\n';
所以我认为这是本书中的一个错误,我认为因为版本需要一个指针是首选,因为我们传递的指针是否为const(T 将被推断为std::string const* 或std::string* )。
你怎么看?
【问题讨论】:
-
C++ Primer 的哪个版本?
标签: c++ template-argument-deduction function-templates-overloading