Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template function overloading in C++

Tags:

I have the following definition.

using namespace std;  template <typename T> void foo(const T &s) {     cout << 1; }  template <typename T> void foo(const T *s) {     cout << 2; }  int main(int argc, const char * argv[]) {     char str[] =  "ss";     char *s = str;     foo(s);      return 0; } 

Then it outputs

1 

From my understanding, both versions have to go through a const conversion. Then void foo(const T *s) is more specialized and should be invoked. However the compiler chose void foo(const T& s). What is the explanation?

like image 482
Zhe Chen Avatar asked May 22 '16 11:05

Zhe Chen


People also ask

What is overloading of function template?

Template Function Overloading:The name of the function templates are the same but called with different arguments is known as function template overloading. If the function template is with the ordinary template, the name of the function remains the same but the number of parameters differs.

Can we overload template functions?

You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.

What is difference between function overloading and function template?

What is the difference between function overloading and templates? Both function overloading and templates are examples of polymorphism features of OOP. Function overloading is used when multiple functions do quite similar (not identical) operations, templates are used when multiple functions do identical operations.

How is the function overloading different from template class?

10. How is function overloading different from template class? Explanation: The function overloading is multiple functions with similar or different functionality but generic class functions perform the same task on given different types of data.


2 Answers

Some people have pointed out that the parameters of the templates as chosen by the compiler

void f(char * const&) void f(const char *); 

Here, notice that the compiler expects a pointer to char, char*, for the first function and it's a const reference. It may come as a surprise, if you found that for your case it prefers the first template, but for the following two, it will prefer the second

template <typename T> void foo(const T& s) {     cout << 1; }  template <typename T> void foo(T &s) {     cout << 2; } 

So, of course, it will look at the const sometimes. Why didn't it in your case? Because it will only look at the const for a reference if the other function has also a reference.

In your case, from char* to const char* it's a pointer conversion, but from lvalue to const lvalue, it's not actually a conversion. Adding a const by a const reference is ignored by overload resolution except when both functions have reference parameters as in the above case.

like image 140
Johannes Schaub - litb Avatar answered Oct 08 '22 04:10

Johannes Schaub - litb


The reason is because s is a non-const pointer, so int* const& is actually a better match than int const* because it doesn't have to add const to the pointer type.

If s were const qualified then it would be an exact match for the T const* version.

like image 21
user6367439 Avatar answered Oct 08 '22 04:10

user6367439