Compilation problem for friend binary operator in template

  • Follow



Hi all

Any idea whats wrong here?


// forward declarations for non-member friend
template <typename T>
class Vec;

template <typename T>
std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 );

// class itself
template <typename T>
class Vec {

   public:
     friend std::valarray<T>& operator - <>( const Vec& v1, const Vec& v2 );

};

// declaration
template <typename T>
std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 )
{
     return v1.vref() - v2.vref();
}

....to give some context, v1.vref() and v2.vref() return references to
valarray<float>s within Vec<float>s, and valarray<> has the binary '-'
operator defined in the standard library.

Compiles OK on it's own but when I try to use it like this:

Vec<float> a(5), b(5), c(5);

  a.vref() = b - c;

I get the following...

-----------------------------------------------------
/Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h: In function
`std::valarray<_Tp>& HR::operator-(const HR::Vec<T>&, const HR::Vec<T>&)
  [with T = float]':

/Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h:250: error: could not convert
`std::operator-(const std::valarray<_Tp>&, const std::valarray<_Tp>&) [with
  _Tp = float]((+(+v2)->HR::Vec<T>::vref() const [with T = float]()))' to
`std::valarray<float>&'
..-----------------------------------------------------

....but if I just use raw valarray<float>'s instead it compiles & runs fine.
GCC 3.3.

TIA

Michael

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

       _/    _/   _/_/_/        Hopkins Research Limited
      _/    _/   _/    _/
     _/_/_/_/   _/_/_/          Optimal Solutions via Virtual Systems
    _/    _/   _/   _/
   _/    _/   _/     _/         Tel: +44(0) 781 3467 381

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

         `All models are wrong, but some are useful' - George Box




-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 100,000 Newsgroups - 19 Different Servers! =-----

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Michael 4/17/2004 6:26:20 AM

Michael wrote:
> Hi all
> 
> Any idea whats wrong here?
> 
> 
> // forward declarations for non-member friend
> template <typename T>
> class Vec;
> 
> template <typename T>
> std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 );
> 
> // class itself
> template <typename T>
> class Vec {
> 
>    public:
>      friend std::valarray<T>& operator - <>( const Vec& v1, const Vec& v2 );
> 
> };
> 
> // declaration
> template <typename T>
> std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 )
> {
>      return v1.vref() - v2.vref();
> }
> 
> ...to give some context, v1.vref() and v2.vref() return references to
> valarray<float>s within Vec<float>s, and valarray<> has the binary '-'
> operator defined in the standard library.
> 
> Compiles OK on it's own but when I try to use it like this:
> 
> Vec<float> a(5), b(5), c(5);
> 
>   a.vref() = b - c;
> 
> I get the following...
> 
> -----------------------------------------------------
> /Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h: In function
> `std::valarray<_Tp>& HR::operator-(const HR::Vec<T>&, const HR::Vec<T>&)
>   [with T = float]':
> 
> /Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h:250: error: could not convert
> `std::operator-(const std::valarray<_Tp>&, const std::valarray<_Tp>&) [with
>   _Tp = float]((+(+v2)->HR::Vec<T>::vref() const [with T = float]()))' to
> `std::valarray<float>&'
> .-----------------------------------------------------
> 
> ...but if I just use raw valarray<float>'s instead it compiles & runs fine.
> GCC 3.3.
> 

The error message could be better but it's complaining that it can't 
convert from a const reference to a reference. Your friend function 
should be returning a const reference like this:

friend const std::valarray<T>& operator - (const Vec<T>& v1, const 
Vec<T>&  v2 );

You probably have to add a const member function vref to your Vec class.

-- 
sashan
http://www.cs.auckland.ac.nz/~sgov008
Public Key: search www.keyserver.net for key id 0x63B4EBF5


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply sashan 4/18/2004 12:40:22 AM


Michael <mwh_acs@hotmail.com> writes:

> Hi all
>
> Any idea whats wrong here?

I think you snipped too much out of your code fragments.

In general, the fragment you post should be the smallest example
    which can reproduce the problem. Your example can't reproduce 
    the problem you report.

>
>
> // forward declarations for non-member friend
> template <typename T>
> class Vec;
>
> template <typename T>
> std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 );
>
> // class itself
> template <typename T>
> class Vec {
>
>    public:
>      friend std::valarray<T>& operator - <>( const Vec& v1, const Vec& v2 );
>
> };
>
> // declaration
> template <typename T>
> std::valarray<T>&  operator - ( const Vec<T>& v1, const Vec<T>& v2 )
> {
>      return v1.vref() - v2.vref();

Here you are returning a reference to a temporary. Returning a
    reference to a temporary and then using said reference has
    undefined behavior. (gcc 3.3.3 warned me about this.)

> }
>
> ...to give some context, v1.vref() and v2.vref() return references to
> valarray<float>s within Vec<float>s, and valarray<> has the binary '-'
> operator defined in the standard library.
>
> Compiles OK on it's own but when I try to use it like this:
>
> Vec<float> a(5), b(5), c(5);
>
>   a.vref() = b - c;


What does vref() do? What does it return?

>
> I get the following...
>
> -----------------------------------------------------
> /Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h: In function
> `std::valarray<_Tp>& HR::operator-(const HR::Vec<T>&, const HR::Vec<T>&)
>   [with T = float]':
>
> /Users/mwh/ACS/Coding/HR C++ code/cpp/hr_vec.h:250: error: could not convert
> `std::operator-(const std::valarray<_Tp>&, const std::valarray<_Tp>&) [with
>   _Tp = float]((+(+v2)->HR::Vec<T>::vref() const [with T = float]()))' to
> `std::valarray<float>&'
> .-----------------------------------------------------

I tried a few variations, but I could not reproduce either of these
    error messages on gcc 3.3.3 

Eventually I ended up with this:

    #include<valarray>

    // forward declarations for non-member friend
    template <typename T>
    class Vec;

    template <typename T>
    std::valarray<T>  operator - ( const Vec<T>& v1, const Vec<T>& v2 );

    // class itself
    template <typename T>
    class Vec {

       public:

      Vec(int i):a(i){}

         friend std::valarray<T> operator - <>( const Vec& v1, const Vec& v2 );

      std::valarray<T> a;

      std::valarray<T> & vref(){return a;}
      std::valarray<T> const& vref()const{return a;}

    };

    // declaration
    template <typename T>
    std::valarray<T>  operator - ( const Vec<T>& v1, const Vec<T>& v2 )
    {
         return v1.vref() - v2.vref();
    }

    int main()
      {
        Vec<float> a(5), b(5), c(5);

        a.vref() = b - c;
      }

Is it anything like what you wanted?

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 4/18/2004 12:41:53 AM

On Sat, 17 Apr 2004 02:26:20 -0400, Michael wrote:

 > ...but if I just use raw valarray<float>'s instead it compiles & runs fine.
 > GCC 3.3.

Cutting a long story short, change the function operator-() to return a
valarray<> by value instead of reference. Ideally, you should be returning
the class for which you are defining the operator-(), but then again, it
is totally your decision as to what behaviour you desire.

For more information on why to return by value, reffer Scott Meyer's book:
Effective C++ and More Effective C++. Your question is answered in the
first one.

-- 
Regards,
-Dhruv.

Proud to be a Vegetarian.
http://www.vegetarianstarterkit.com/
http://www.vegkids.com/vegkids/index.html


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Dhruv 4/18/2004 10:01:26 AM

3 Replies
113 Views

(page loaded in 0.083 seconds)

Similiar Articles:






7/24/2012 1:29:48 PM


Reply: