Qualifying a friend function

The following code suffers from infinite recursion.  Other than changing the name of GetDistance that's "scoped" in Foo or in Base<Foo> and its derivitive Bar, how would I go about changing this code so that Bar::GetDistance delegates to the GetDistance that's "scoped" in Foo

class Foo
{
public:
   friend double GetDistance( Foo& f1, Foo& f2 )
   {
     return 0;
// or some distance metric
   
}
};

template <class T>
class Base
{
    virtual double GetDistance( T& f1, T& f2 ) = 0;
};

class Bar : Base<Foo>
{
public:
    /*override*/ double GetDistance( Foo& f1, Foo& f2 )
   {
      return GetDistance( f1, f2 );
   }
};

int main()
{
   Bar bar1;
   Foo f1, f2;
   bar1.GetDistance( f1, f2 );
   return 0;
}

Note that

return Foo:GetDistance( f1, f2 );

gives the error:

error C2039: 'GetDistance' : is not a member of 'Foo

Thanks.

Brian



Answer this question

Qualifying a friend function

  • shauli

    You could declare the GetDistance function friend within Foo, and define it at namespace scope.

    class Foo
    {
    public:
      friend double GetDistance( Foo& f1, Foo& f2 );
    };

    double GetDistance( Foo& f1, Foo& f2 )
    {
      return 0; // or some distance metric
    }

    Then you could qualify the call from Bar, such as

    /*override*/ double GetDistance( Foo& f1, Foo& f2 )
    {
      return ::GetDistance( f1, f2 );
    }



  • &amp;#321;ukasz Sromek

    The GetDistance defined within Foo in your example will also "be" in namespace scope, though. It'll merely be harder to reach.

  • CraigInCalifornia

    What's the motivation for not making GetDistance a static member of Foo Unless Foo is templated, that should do the trick.

  • Wings_That_Fly

    True. I should probably add that there is another flavor of Bar that also derives from Base<Foo>. Adding another namescape for the corresponding bridge function probably won't work.
  • ejb111us

    I think that's the right approach: make it static instead.  (Aside: it turns out that I no longer use it as a friend function, and there are no private members that need accessing, but I have the option of keeping having both functions in Foo if I ever needed the friend behavior--kind of strange though.)

    Thanks, Einar!


  • CET PRG455

    Yeah, but renaming Foo::GetDistance (my current workaround) is less of a change than add a namespace-scoped function.
  • Qualifying a friend function