Thread: Specialing template for pointers

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    13

    Specialing template for pointers

    Is the template :
    Code:
    template<class T> void function1(T* t);
    a specialization of the template:
    Code:
    template<class T> void function1(T t);
    ?. Do I have to specialize it for void* and derive from it?
    Last edited by Sajas K K; 02-10-2013 at 09:08 PM.

  2. #2
    Registered User
    Join Date
    Dec 2012
    Posts
    13
    Sorry for asking such adumb question. I got the answer. It seems to specialize the template. Don't know how to delete a thread. Sorry about that..

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    a specialization of the template
    O_o

    There is no specialization in your post.

    Templates are involved, but that fact is irrelevant. That is function overloading.

    They are very different beasts.

    Do I have to specialize it for void* and derive from it?
    You don't have to derive templates from other templates even when specialization is involved.

    Soma

  4. #4
    Registered User
    Join Date
    Dec 2012
    Posts
    13
    Quote Originally Posted by phantomotap View Post
    O_o

    There is no specialization in your post.

    Templates are involved, but that fact is irrelevant. That is function overloading.

    They are very different beasts.



    You don't have to derive templates from other templates even when specialization is involved.

    Soma
    Thanks for pointing out my mistake.. I thought it was specialization of the template to work on pointers..

  5. #5
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    A specialization is that you provide a special implementation of a template function (or class or template whatever) based on the template arguments.
    Code:
    template<typename T>
    void func(const T &bla) { // This is the generic case }
    
    template<>
    void func(const int &bla) { // int is a special case }
    The second function is a template specialization of func for when T is int.

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    13
    Quote Originally Posted by Shakti View Post
    A specialization is that you provide a special implementation of a template function (or class or template whatever) based on the template arguments.
    Code:
    template<typename T>
    void func(const T &bla) { // This is the generic case }
    
    template<>
    void func(const int &bla) { // int is a special case }
    The second function is a template specialization of func for when T is int.
    But there is partial specialization as well, right? Like:
    Code:
     template<class T> void func(complex<T>)

  7. #7
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Not sure if that classifies as partial specialization or not, since you have clearly specialized func for all complex types, but you could provide even more specialized versions if you want to...

    This more clearly demonstrates partial specialization:
    Code:
    #include <iostream>
    
    template<typename T, typename U>
    void Func(T t, U u)
    {
        std::cout << "Fully generic" << std::endl;
    }
    
    template<typename U>
    void Func(int t, U u)
    {
        std::cout << "Partially specialized for int" << std::endl;
    }
    
    template<>
    void Func(int t, int u)
    {
        std::cout << "Fully specialized for int" << std::endl;
    }
    
    
    int main()
    {
        Func(10.0, 10.0);
        Func(10, 10.0);
        Func(10, 10);
    }
    Output should be
    Code:
    Fully generic
    Partially specialized for int
    Fully specialized for int
    Last edited by Shakti; 02-11-2013 at 07:14 AM.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    But there is partial specialization as well, right?
    No. It is not a specialization. It is just another function which has an overloaded name that happens to be a template.

    This more clearly demonstrates partial specialization
    (I know you are being helpful so I will do my best to avoid any snark. If you see any, it is accidental; I intend no offense.)

    No. That is not partial specialization.

    Why? There is no template on which the function you think to be a partial specialization depends.

    Code:
    template <typename T> class Test{};
    template <typename T> class Test<T*>{};
    The second line, the partial specialization, depends on the first line, the original template, to "function".

    That is partial specialization.

    What you have for your second function, the one you think is partially specialized, is just an overloaded function.

    Simply put, you can't directly partially specialize a function template; you will always either get a specialized template or just another template function.

    The function in question, the second one, is just a template which takes an `int' first parameter and a generic second parameter.

    The third function is a specialization. Here it is a specialization of the second function. If you were to remove the second function from your example is would become a specialization for the first template. If you remove both, it will not compile because it is a specialization that depends on an original template.

    This bring us to the first "tip": when it comes to functions, if you don't have `template<>' you don't have a specialization.

    Before we move on, we need another example. I'm going to borrow from the one Shakti posted.

    Code:
    #include <iostream>
    
    template<typename T, typename U>
    void Func(T t, U u)
    {
        std::cout << "Fully generic" << std::endl;
    }
    
    template<>
    void Func(int t, int u)
    {
        std::cout << "Fully specialized for int" << std::endl;
    }
    
    template<typename U>
    void Func(int t, U u)
    {
        std::cout << "Partially specialized for int" << std::endl;
    }
    
    
    int main()
    {
        Func(10.0, 10.0);
        Func(10, 10.0);
        Func(10, 10);
    }
    I only moved the third function, a specialized template, above the second function forcing it to be a specialization of the first function.

    What is the problem?

    Code:
    Fully generic
    Partially specialized for int
    Partially specialized for int
    The output isn't what you thought it would be, is it?

    The second function, originally the third, isn't considered at all by the compiler. The compiler only looks at the other two template functions for overload resolution. It sees that the third function, originally the second, is more appropriate and so chooses it. That function has no specializations so the compiler stops looking and just uses that function.

    In the original, the compiler still looks at the same two templates for overload resolution. The only difference, seen because in the original the third function was a specialization of the second, the second function which is a better match has a specialization which the compiler will look through because the "base" template was chosen during overload resolution.

    This bring me to my second "tip": specialization do not participate in overload resolution the same as simple functions and function templates.

    Before we continue, we need another example, only this time, I'm going to use the same code Shakti posted.

    How is this example different? Let's put our two template functions and the specialization (the three functions named `Func') in a header so we can reuse them in all their glory.

    So, we now have three files in our project: "func.h", "main.cpp", and "more.cpp".

    For the sake of simplicity, let's just assume both "main.cpp" and "more.cpp" call all three functions.

    Now, let's link our code into a binary application.

    Failure!

    So, what's the problem?

    We got a linker error because specialized template functions are not templates. (You: What?)

    It is a complicated mess, and I'm not going to go into why this behavior is necessary (Yes, believe it or not, all of the behavior related to templates functions discussed here it to be preferred), but the simple view is: template function specializations are templates, but not overloads, to a compiler and functions, but not templates, to a linker.

    Why is this all so complicated? There are reasons; you'll just have to either research yourself or take my word for it.

    Fortunately, it simply does not have to be so complicated for almost all cases.

    How do you avoid this complexity?

    This bring us to the third "tip": don't specialize template functions.

    You will almost never want a specialized template function.

    Instead of trying to specialize a template function, just overload the function as you would normally optionally marking it `inline', and possible `static', if you want to include the source in headers with your templates functions.

    Why? It solves all of our problems which I've discussed. (For example, it would not matter where you put the third function, second in my example, if it was just a function because it would participate in overload resolution.)

    You are now free to enjoy your newly discovered "OH. MY. GOD! WHY IS C++ SO COMPLICATED!?" because I'm done discussing this... for now.

    Mwhahahahaha!

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 04-06-2011, 01:37 PM
  2. Replies: 3
    Last Post: 01-30-2011, 04:28 PM
  3. Template of class pointers
    By @nthony in forum C++ Programming
    Replies: 8
    Last Post: 11-09-2008, 07:17 AM
  4. Replies: 4
    Last Post: 11-01-2006, 02:23 PM
  5. problem instantiating template with pointers
    By Sebastiani in forum C++ Programming
    Replies: 10
    Last Post: 03-15-2006, 06:28 PM