Yuushi
Yuushi

Reputation: 26080

Function template overloading resolution involving pointers

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

Answers (2)

jahhaj
jahhaj

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

Kerrek SB
Kerrek SB

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

Related Questions