CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Apr 2003
    Location
    Morelia, Mexico
    Posts
    40

    new way of overloading operators in templates??

    First of all, this code does compile with g++ 3.3.5. But with g++ 4.0.2 it gives me a few errors. g++ enters the #else portion. The _MSC_VER is meant to be able to compile it in VC++ 5

    Code:
    #ifdef _MSC_VER
            friend CMatriz<TG> operator+(const TG &op1,const CMatriz<TG> op2); // objeto TG + CMatriz
            friend CMatriz<TG> operator+(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    #else /*Next line is 64*/
            friend CMatriz<TG> operator+ <>(const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
            friend CMatriz<TG> operator+ <>(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    #endif
    The compiler says:
    Matriz.h:64: error: declaration of 'operator+' as non-function
    This error happens too with another operators. However with the <<:

    Code:
    #ifdef _MSC_VER
            friend ostream &operator<<(ostream &os,const CMatriz<TG> &op);
    #else /*Next line is 87*/
            friend ostream &operator<< <>(ostream &os,const CMatriz<TG> &op);
    #endif
    The compiler gives a different error:
    Matriz.h:87: error: template-id 'operator<< <>' for std::basic_ostream<char, std::char_traits<char> >& operator<<(std::basic_ostream<char, std::char_traits<char> >&, const CMatriz<CComplejo>&)' does not match any template declaration

    Any clues as to how should these be declared?
    int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
    o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

  2. #2
    Join Date
    Apr 2003
    Location
    Morelia, Mexico
    Posts
    40

    Re: new way of overloading operators in templates??

    For the record, I solved the ostream << problem by adding:
    Code:
    template<class TG> class CMatriz;
    template<class TG> ostream& operator<< (ostream & os, const CMatriz<TG> &op);
    Before declaring the template class. I haven't found the way to fix it for the other operators.
    Last edited by Luis G; June 30th, 2006 at 11:22 AM.
    int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
    o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

  3. #3
    Join Date
    May 2006
    Posts
    327

    Re: new way of overloading operators in templates??

    Maybe for friend declarations you should try this:

    Code:
    template< class W >
    friend CMatriz<W> operator+ (const W &op1,const CMatriz<W> &op2); // objeto W + CMatriz
    template< class W >
    friend CMatriz<W> operator+ (const double &op1, const CMatriz<W> &op2); // constante + CMatriz
    I hope it helps.

  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: new way of overloading operators in templates??

    What are the empty angle brackets doing?
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    Join Date
    Apr 2006
    Location
    Nr Cambridge, UK
    Posts
    263

    Re: new way of overloading operators in templates??

    In order to use the <> versions, declarations of the templates in question have to be visible. So you need:
    Code:
    template<class TG> class CMatriz;
    template<class TG> ostream& operator<< (ostream & os, const CMatriz<TG> &op);
    template< class W >
    CMatriz<W> operator+ (const W &op1,const CMatriz<W> &op2); 
    template< class W >
    CMatriz<W> operator+ (const double &op1, const CMatriz<W> &op2); 
    
    template<class TG> class CMatriz
    {
      //friends, etc.
    };
    Also, the friend declarations would be more explicit if you specified the template argument, rather than leaving it up to template argument deduction. e.g.
    Code:
    friend CMatriz<TG> operator+ <TG>(const double &op1,const CMatriz<TG> &op2);

  6. #6
    Join Date
    Apr 2006
    Location
    Nr Cambridge, UK
    Posts
    263

    Re: new way of overloading operators in templates??

    Quote Originally Posted by Graham
    What are the empty angle brackets doing?
    If you don't have them, the compiler assumes that the friend declaraton refers to a non-template function from the surrounding namespace, so the template function that is supposed to be a friend isn't made one.

  7. #7
    Join Date
    Apr 2003
    Location
    Morelia, Mexico
    Posts
    40

    Re: new way of overloading operators in templates??

    Many thanks for the help, I've done what you said but it still gives the same errors.

    This is how it looks now:
    Code:
    template<class TG> class CMatriz;
    template<class TG> ostream& operator<< (ostream & os, const CMatriz<TG> &op);
    template<class TG> CMatriz<TG> operator+ (const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
    template<class TG> CMatriz<TG> operator+ (const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    template<class TG> CMatriz<TG> operator* (const TG &op1,const CMatriz<TG> &op2); // Objeto TG por matriz
    template<class TG> CMatriz<TG> operator* (const double &op1,const CMatriz<TG> &op2); // Constante por matriz
    
    template<class TG> class CMatriz
    {
    public:
            CMatriz(unsigned int j=1,unsigned int k=1);
            CMatriz(const CMatriz<TG> &cpv);
            ~CMatriz();
            // Other stuff here
            //....... below is line 74
            friend CMatriz<TG> operator+ <>(const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
            friend CMatriz<TG> operator+ <>(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
            //....... below is line 90
            friend CMatriz<TG> operator* <>(const TG &op1,const CMatriz<TG> &op2); // Objeto TG por matriz
            friend CMatriz<TG> operator* <>(const double &op1,const CMatriz<TG> &op2); // Constante por matriz
            //.......
    protected:
            //.......
    }
    
    /** Other functions 
    .....
    */
    
    template<class TG>
    CMatriz<TG> operator+(const TG &op1,const CMatriz<TG> &op2)
    {
            unsigned int j,k;
            CMatriz<TG> suma(op2.m_reng,op2.m_cols);
            for(j=0;j<op2.m_reng;j++)
                    for(k=0;k<op2.m_cols;k++)
                            suma.inserta(j,k,op2.obten(j,k)+op1);
    
            return suma;
    }
    The errors reported:
    Code:
    legg@lc65:~/tempo$ make
    g++ -O -g -I. -DLinux -Wall -c main.cpp
    Matriz.h:74: error: declaration of 'operator+' as non-function
    Matriz.h:74: error: expected ';' before '<' token
    Matriz.h:75: error: declaration of 'operator+' as non-function
    Matriz.h:75: error: expected ';' before '<' token
    Matriz.h:90: error: declaration of 'operator*' as non-function
    Matriz.h:90: error: expected ';' before '<' token
    Matriz.h:91: error: declaration of 'operator*' as non-function
    Matriz.h:91: error: expected ';' before '<' token
    Matriz.h: In function 'CMatriz<TG> operator*(const double&, const CMatriz<TG>&) [with TG = int]':
    main.cpp:39:   instantiated from here
    Matriz.h:102: error: 'unsigned int CMatriz<int>::m_reng' is protected
    Matriz.h:354: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<int>::m_cols' is protected
    Matriz.h:354: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<int>::m_reng' is protected
    Matriz.h:355: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<int>::m_cols' is protected
    Matriz.h:356: error: within this context
    Matriz.h: In function 'CMatriz<TG> operator*(const double&, const CMatriz<TG>&) [with TG = CComplejo]':
    main.cpp:87:   instantiated from here
    Matriz.h:102: error: 'unsigned int CMatriz<CComplejo>::m_reng' is protected
    Matriz.h:354: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<CComplejo>::m_cols' is protected
    Matriz.h:354: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<CComplejo>::m_reng' is protected
    Matriz.h:355: error: within this context
    Matriz.h:102: error: 'unsigned int CMatriz<CComplejo>::m_cols' is protected
    Matriz.h:356: error: within this context
    make: *** [main.o] Error 1
    The protected errors are spurious (should be).

    If I include a declaration like:
    Code:
            friend CMatriz<TG> operator* <TG>(const double &op1,const CMatriz<TG> &op2); // Constante por matriz
    It won't compile under 3.3 either.
    Last edited by Luis G; June 30th, 2006 at 03:44 PM.
    int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
    o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

  8. #8
    Join Date
    Apr 2003
    Location
    Morelia, Mexico
    Posts
    40

    Re: new way of overloading operators in templates??

    I found out. The correct code is:

    Code:
    #ifdef _MSC_VER 
    	friend CMatriz<TG> operator+(const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
    	friend CMatriz<TG> operator+(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    #elif __GNUC__ > 3 || (__GNUC__==3 && __GNUC_MINOR__ >=4)
    	friend CMatriz<TG> (::operator+ <TG>)(const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
    	friend CMatriz<TG> (::operator+ <TG>)(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    #else
    	friend CMatriz<TG> operator+ <>(const TG &op1,const CMatriz<TG> &op2); // objeto TG + CMatriz
    	friend CMatriz<TG> operator+ <>(const double &op1,const CMatriz<TG> &op2); // constante + CMatriz
    #endif
    The code I was after is the one meant for gcc>=3.4, that however won't compile in 3.3

    Any idea as to what does the new code means?
    Last edited by Luis G; June 30th, 2006 at 03:50 PM.
    int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
    o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

  9. #9
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: new way of overloading operators in templates??

    Quote Originally Posted by Graham
    What are the empty angle brackets doing?
    Assuming we are referring to the same thing, I am sure you know why you use empty angle brackets in template friend specifications.

    Code:
    template < typename T > class Matriz;
    
    template < typename T > std::ostream &
    operator<< ( std::ostream &, const Matriz< T > & );
    
    template < typename T >
    class Matriz
    {
       friend std::ostream & operator<< <> ( std::ostream &, const Matriz & );
     
      // rest of template Matriz
    };
    
    template < typename T >
    std::ostream & operator<< ( std::ostream & os, const Matriz<T> & mat )
    {
     // implement here
    }
    The angled brackets in friend declaration tell the compiler that it is a template function.

  10. #10
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: new way of overloading operators in templates??

    I was suggesting looking into the reason why they were there in one conditional section, but not in the other (unless it was down to compiler silliness - which seems probable, given mention of VC5).

    Mind you, I rarely use friends, and I don't think I've ever coded a template friend...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured