Thread: Function template overload/specialisation

  1. #1
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    Function template overload/specialisation

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <class T> void f(T a)
    {
        cout << "a) using template\n";
    }
    
    template <class T> void f(T* a)
    {
        cout << "b) using overloaded template\n";
    }
    
    template <> void f<int*>(int* a)
    {
        cout << "c) using specialised template\n";
    }
    
    int main()
    {
        int x = 1;
        int* px = &x;
        f(px);
    
        return 0;
    }
    If I compile and run the above program, function b) is called. For some reason, the compiler is treating function c) as a specialisation of a) and not as a specialisation of b).

    However, if I change the prototype of function c) from
    Code:
    template <> void f<*int>(int* a)
    to
    Code:
    template <> void f<>(int* a)
    , then the compiler treats c) as a specialisation of b), and c) is called.

    Can anybody explain to me why this should be the case? I would have expected function c) to have been called in the original version too. Thanks in advance for any help.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think for functions you simply provide a non-template overload that would be preferred to template overloads. (Functions are not specialized, they are overloaded.)

    Code:
    void f(int* a)
    {
        cout << "c) using specialised template\n";
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    I can see that would make more sense in practice. However, right now I'm still just learning C++ rather than trying to use it for anything in particular, and this is really bugging me.

    Anyhow, in The C++ Programming Language, Bjarne Stroustrup say that:

    Code:
    template<>bool less<const char*>(const char* a, const char*b);
    
    template<>bool less<>(const char* a, const char* b);
    
    template<>bool less(const char* a, const char* b);
    are all equiavent.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Ok, you can read about your very own example in this article (Why Not Specialize Function Templates).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    I read that article earlier today - unfortunately it doesn't seem to explain why inserting/omitting the redundant parameter type specification should have any effect on what the specialisation is a specialisation of.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    As I understand

    Code:
    template <> void f<int*>(int* a)
    could be (or perhaps even is required to be as it would actually seem to make more sense) a specialization of

    Code:
    template <class T> void f(T a)
    and not of

    Code:
    template <class T> void f(T* a)
    so if the compiler has to pick between the two overloads first (T or T*) it picks the T* version as a better match and then sees that that doesn't have any further specializations.

    I might be off with that analysis because in practice you would simply avoid getting that deep into the template resolution rules. In any case the important point seems to be that the T* version is not a specialization of the T version.
    Last edited by anon; 12-18-2008 at 07:54 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    But understanding your question better now, the difference between

    Code:
    template <> void f<int*>(int* a);
    template <> void f<int>(int* a);
    template <> void f<>(int* a);
    template <> void f(int* a);
    might be (as I understand)

    - the first case falls under the first overload (where T = int*). BTW, the first overload would be picked if you mention the <int*> template argument explicitly in the call.

    - the second case falls under the second overload (where T = int). Since the second overload is picked implicitly always, now the further specialization is available.

    - what exactly the third and fourth is supposed to mean is somewhat of a mystery to me that might be looked up in the standard if you can find anything relevant.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. function template question
    By Thantos in forum C++ Programming
    Replies: 3
    Last Post: 04-18-2004, 10:40 AM