Thread: Operator overload with template class

  1. #1
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715

    Operator overload with template class

    Hello people,
    I didn't write any C++ code and became little rusty.
    I cannot figure why the following code:
    Code:
    #include <iostream>
    
    using namespace std;
    
    template <typename T>
    class Int
    {
        T x;
    public:
        Int(int);
        Int(const Int<T>&);
        Int<T>& operator =(const Int<T>&);
        friend Int<T> operator +(const Int<T>&, const Int<T>&);        
        void show()
        {
            cout << x;
        } 
    
    };
    
    template <typename T>
    Int<T>::Int(int t):x(t)
    {
    }
    template <typename T> 
    Int<T>::Int(const Int<T>& ti)
    {
        x = ti.x;
    }
    template <typename T> 
    Int<T>& Int<T>::operator =(const Int<T>& ti)
    {
        if (this != &ti)
        {
            x = ti.x;
        }
        return *this;
    }
    template <typename T> 
    Int<T> operator +(const Int<T>& first, const Int<T>& second)
    {
        return Int<T>(first.x+second.x);
    }
    
    int main(int argc, char *argv[])
    {
        Int<int> a(4), b(5), c(0);
        c = a+b;
        c.show();
        return 0;
    }
    generate linker error?
    Can friend function be used when working with templates?
    If I overload operator + as member function, everything works.
    What would be explanation for such behavior?

    Thanks
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You are defining a templated operator overload, but not declaring it templated inside the class definition.

    Change to:

    Code:
    template <typename TT>
    friend Int<TT> operator +(const Int<TT>&, const Int<TT>&);
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thanks for replying Mario.
    I changed line
    Code:
    friend Int<T> operator +(const Int<T>&, const Int<T>&);
    to
    Code:
    template <typename TT>
        friend Int<TT> operator +(const Int<TT>&, const Int<TT>&);
    and it works. Please can you explain a little more why line templete <typename T> before class definition was not enough?
    If I understood correctly, friend function is not a member function, therefore line "templete <typename T>" didn't work. That's why function template needed to be defined separately. Am I right here?
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > If I understood correctly, friend function is not a member function, therefore line "templete <typename T>" didn't work. That's why function template needed to be defined separately. Am I right here?

    Yup. That's it. Not being a member function forces you to specify the template argument list of the function. You are specifying here the template parameter of the operator+() function, not of the class.

    Member functions are members of the class (well... duh! ) as such, their template parameter(s) is the one you specified for the class as a whole.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Well, there is one thing to take into consideration. The above will establish a one-to-many relationship between a class instance and the operator+() function. That is, for each Int object all instantiations of operator+() are friends.

    So you can incur in unwanted behavior when you try to do something like this:

    Code:
    Int<int> a(4);
    Int<double> b(5);
    Int <float> c(0);
    
    c = a + b;
    It may be ok. You may want the implicit conversions. If you do not want this behavior you must establish a one-to-one relationship in which each class instantiation maps only to one function instantiation with the same template argument.

    For that, you have to revert to the way you had your code in the initial post. Then you first need to make a declaration of the function before the class definition...

    Code:
    template <typename T>
    Int<T> operator +(const Int<T>&, const Int<T>&);
    
    template <typename T>
    class Int
    {
    /*... */
    This guarantees that the function declared inside the class is already known to the compiler. The name is in scope. However, you will now get an error on that function declaration line complaining about Int not being declared... So we forward-declare it...


    Code:
    template <typename T>
    class Int;
    
    template <typename T>
    Int<T> operator +(const Int<T>&, const Int<T>&);
    
    template <typename T>
    class Int
    {
    /*... */
    And then we get an error complaining about the function inside the class being declared as non-template (again!). So... we declare it as a template with an empty pair of ... whatever those signs are called....

    Code:
    template <typename T>
    class Int;
    
    template <typename T>
    Int<T> operator +(const Int<T>&, const Int<T>&);
    
    template <typename T>
    class Int
    {
        T x;
    public:
        Int(int);
        Int(const Int<T>&);
        Int<T>& operator =(const Int<T>&);
        friend Int<T> operator +<>(const Int<T>&, const Int<T>&);
        void show()
        / *... */
    And so it is. Now if you try the following code you don't even need to wait for a run-time error. The compiler will immediately warn you.

    Code:
    Int<int> a(4), b(5);
    Int<float> c(0);
    c = a+b;  // compiler issues error here.

    EDIT: Keeping this post because... well, it still has its uses. However while correct, the premise is wrong. You will not face the problem of unwanted conversions because there's one 1 template parameter that maps to both the function arguments and the return type. The compiler will always complain. You don't need the text on this post. Sorry about that. Wasn't thinking.
    Last edited by Mario F.; 12-15-2006 at 06:57 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #6
    Registered User
    Join Date
    Jul 2011
    Posts
    1

    Thanks

    works fine with:
    g++ --version
    g++ (GCC) 4.6.0 20110530 (Red Hat 4.6.0-9)

    Thanks.

    Quote Originally Posted by Mario F. View Post
    You are defining a templated operator overload, but not declaring it templated inside the class definition.

    Change to:

    Code:
    template <typename TT>
    friend Int<TT> operator +(const Int<TT>&, const Int<TT>&);

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is a Lite C++ FAQ here: C++ FAQ
    It includes a section on templates. It might be helpful.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    This is a 5 year old thread.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Closed

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. template and friend class
    By black_spot1984 in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2008, 05:50 PM
  2. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  3. Instantiating a template class
    By NullS in forum C++ Programming
    Replies: 11
    Last Post: 02-23-2005, 10:04 AM
  4. Function template in Class template?
    By Aidman in forum C++ Programming
    Replies: 3
    Last Post: 10-28-2003, 09:50 AM
  5. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM