Reputation: 26080
Given a template and a more specialized overload:
template <typename T>
const T& some_func(const T& a, const T& b)
{
std::cout << "Called base template\n";
return (a < b) ? a : b;
}
template <typename T>
T* const& some_func(T* const& a, T* const& b)
{
std::cout << "Called T* overload\n";
return (*a < *b) ? a : b;
}
Then the following works as expected:
int main()
{
std::cout << some_func(5.3, 6.2) << "\n";
double a = 1;
double b = 2;
double *p = &a;
double *q = &b;
const double *ret = some_func(p, q);
std::cout << *ret << "\n";
return 0;
}
With the first printing Called base template
, the second printing Called T* overload
. If we replace the overload signature with:
template <typename T>
const T*& some_func(const T*& a, const T*& b)
then the second call now calls the base template. Given that int const& x
is equivalent to const int& x
, am I incorrect in assuming T* const&
is equivalent to const T*&
? Why is the first version resolved properly while the second is not?
Upvotes: 1
Views: 109
Reputation: 3119
Yes you are incorrect. In const T*&
T is const, in T* const&
the pointer (T*) is const.
The change happens when you shift const
to the right of *
. const T*&
and T const *&
are equivalent but T* const&
is different. Typedefs can help, given
typedef T *TPtr;
const TPtr&
is equivalent to TPtr const &
is equivalent to T* const &
.
Declarators in C/C++ are hard to parse (for a human). Even the inventor of C said so.
Upvotes: 5
Reputation: 477464
T const &
and const T &
are identical; and U const *
and const U *
are identical.
But S &
and T const &
are not the same even for T = S
. What you have is even worse, namely S = U const *
and T = U *
.
Upvotes: 2