Reputation: 657
Consider the code below:
#include <iostream>
// General overload using a template
template <typename SomeType>
void some_func(const SomeType p) {
std::cout << "Using the general function" << std::endl;
}
// Specific overload, accepting a 'const double*' type
void some_func(const double* p) {
std::cout << "Using the function accepting a const double*" << std::endl;
}
int main() {
// This one uses the specific overload, as expected
const double *a = new double(1.1);
some_func(a);
delete a;
// This one uses the general function rather than the second overload
double *b = new double(1.1);
some_func(b);
delete b;
return 0;
}
In this piece of code, there are two overloads of the some_func
function. The first one is the most general overload, using a template to capture practically any type. The second overload is a specific overload, accepting a const double*
type as its argument.
In the main
function, I first create the variable a
of type const double*
. When supplying a
to some_func
, the second overload is selected. This is as expected. Secondly, I create a variable b
of type double*
(so no const
). When supplying the variable b
to some_func
, it selects the first overload. I would've expected it to select the second overload, as (I think) it should be able to implicitly convert a type double*
to const double*
. Why does it select the first overload rather than the second overload in this case?
For completeness, this is the output of the program:
$ g++ main.cpp
$ ./a.out
Using the function accepting a const double*
Using the general function
Upvotes: 1
Views: 102
Reputation: 151
During template instantiation, this const SomeType p
would turn into double* const p
which is a better match than const double*
. That is, the template's parameter would become a const-pointer to mutable data.
In the template function, you can actually modify the data through that pointer, so it can be assumed it is a better match.
If you change const SomeType p
to const SomeType* p
, the specific overload will be selected.
Upvotes: 2
Reputation: 3272
The qualifier const
is a kind of a contract. Here is means that the function won't be able to change the value by the pointer
So the compiler has two options:
Having the argument which could be changed, it is logical to choose the first case.
So, following the rule of selecting with precise type, taking into account CV-qualifiers very logical.
Upvotes: 2