In the book C++ Primer, there is an example about function template overloading:
// 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.
But if I declare the pointer to string as const
although there's no conversion the second version is always chosen:
string const s("hi"); // const
cout << debug_rep(&s) << '\n';
So I think it is a mistake in the book and I think because the version takes a pointer is preferred because we pass a pointer being const
or not (T
will be deduced as std::string const*
or std::string*
).
What do you think?
A template function can be overloaded either by a non-template function or using an ordinary function template.
A function template can be overloaded with other function templates and with normal (non-template) functions. A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.)
………. …… ….. ……. where, T is template argument accepting different arguments and class is a keyword. The name of the function templates are the same but called with different arguments is known as function template overloading.
A template function can be overloaded either by a non-template function or using an ordinary function template. Function Overloading: In function overloading, the function may have the same definition, but with different arguments. Below is the C++ program to illustrate function overloading:
To reduce these efforts, C++ has introduced a generic type called function template. Function Template: The function template has the same syntax as a regular function, but it starts with a keyword template followed by template parameters enclosed inside angular brackets <>. ………. …… ….. …….
Are you learning C++ language currently? If yes, then learning to use templates can make your work easier than ever! The template is the first document that is created for use on a given topic. It defines the overall structure or format for subsequent documents.
The book is wrong.
In the first example, the instantiation generated is not debug_rep(const string* &)
, it is debug_rep(string* const&)
. That is, const
qualifies the pointer, not the thing pointed to. (This would be more obvious if the book used right const; that is, template <typename T> string debug_rep(T const& t)
for the first function template.)
Indeed, T
and T const&
have equal priority as function template overloads; where they form an overload set it will be ambiguous. The reason T*
is chosen over T const&
is that it is more specialized; simply put, an arbitrary T*
can be passed to a function taking T const&
, while an arbitrary T const&
cannot be passed to a function taking T*
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With