34

Is it not supposed for a friend function to be explicitly defined outside of a class ?
If so why can i declare a friend function inside a class definition just like any member function ?
What is this ?
Is it only OK with some operators such as < operator or is it applicable to all operators?
If it is applicable to all of them, Is there any disadvantage for doing this ?
Should it be avoided? If so why ?

class person 
{
public:
    bool operator<(int num)
    {
        return  x < num ? true : false ;
    }
    bool operator<(person& p)
    {
        return  x < p.x ? true : false ;
    }

    friend bool operator<(int num, person &p)
    {
        return  p.x < num ? true : false ;
    }

    void setX(int num)
    {
        x = num;
    }

private:
    int x;


};

Update:
I am not asking for choosing non-member operator overloading or member operator overloading.
What i want to know is that :
Why we are permitted to move the definition of friend methods inside our class definition?.
Is it not violating any things? If it is not, Why would we have friends in first place?
We could simply define overloads as member functions ( I know the limitations of member functions ) But i am saying knowing this, Why isn't compiler complaining that I haven't defined friend function outside a class definition since it doesn't need to be inside of it (because of the class parameter it has) So why are we allowed to define a friend function inside a class definition?

Hossein
  • 24,202
  • 35
  • 119
  • 224

5 Answers5

13

Is it not supposed for a friend function to be explicitly defined outside of a class ?

Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions, and like member inline functions they behave as though they were defined immediately after all class members have been seen but before the class scope is closed (the end of the class declaration). Friend functions that are defined inside class declarations are in the scope of the enclosing class. quote

Is it only OK with some operators such as < operator or is it applicable to all operators?

It is best to try to avoid friend functions since they are opposite to what you are trying to do using a private class scope and mainly "hide" the variables. If all your functions are friend functions then what is the use of having private variables?

Still, there are some common operators which are often declared as friend functions, those are operator<< and operator>>

faressalem
  • 574
  • 6
  • 20
Alexandru Barbarosie
  • 2,952
  • 3
  • 24
  • 46
  • Thank you very much :) I am not trying to declare all of my needed functions as friends, I was curios to know why a friend function (which is solely used for operating overloading and nothing else) can be defined inside a class and why it is permitted – Hossein Jul 07 '13 at 13:49
  • @Hossein the quote I gave you doesn't atually say "why it is permited" but explains why "it is not not permited". – Alexandru Barbarosie Jul 07 '13 at 13:52
  • i know , but the part "Friend functions can be defined inside class declarations" , says we are premitted to do so, i understand that friend functions are not an answer for everything as you have also clearly mentioned , when i was saying that , i meant the quoted section which kinda cleared parts of my question – Hossein Jul 07 '13 at 14:01
  • They are "in file scope"? Shouldn't they be inserted into the surrounding scope, be it file, namespace, function, class? – Felix Dombek Feb 20 '19 at 14:34
  • `Friend functions that are defined inside class declarations are in the scope of the enclosing class`. Not sure this part is accurate. At least I can't spot any difference between friend functions defined inside of a class declaration and outside of it - both act as free functions without extra scope restriction. – The Dreams Wind Oct 10 '22 at 16:07
6

Alexandru Barbarosie answer is correct. It means that we can declare a friend function, which is not a member function, within a class. This can be nice to organize the code. I think an example can help to understand it in case it isn't clear.

#include <iostream>

class A {
    public:
        A(int val) : val(val) {}
        // The following isn't a member function, it is a friend 
        // function declared inside the class and it has file scope
        friend void draw (A &a) {
            std::cout << "val: " << a.val << "\n";
        }
    private:
        int val;
};

int main() {
    A a(5);
    draw(a); // outputs "val: 5"
    //A::draw(a); // Error: 'draw' is not a member of 'A'
}
Blasco
  • 1,607
  • 16
  • 30
5

If you are creating a header-only class (which makes deployment vastly easier) then defining a friend function within the class is the only way to go since definitions can only appear in a single translation unit. The normal technique of include guards doesn't work since that only handles things like recursive inclusion.

This can be a big deal if you are trying to write standards-conformant code. For example, to implement the RandomNumberEngine named requirement from the C++ normative standard, it is necessary to provide operator<<. This has to be a friend to take a std::ostream& object as its first parameter (otherwise it will look like a normal, single parameter member function operator overload). Ordinarily the friend declaration would go in the class definition and and the function definition in a separate .cpp source file. But if you want a header-only implementation, it must be defined in the class to avoid multiple definition errors.

David G
  • 5,408
  • 1
  • 23
  • 19
  • 2
    *"defining a friend function within the class is the only way to go"* One could also use `inline` functions. – HolyBlackCat Oct 24 '19 at 19:26
  • @HolyBlackCat true, up to a point. However I'm not happy about doing this since inlines with non-static linkage do not need to be the same across translation units, and that's just asking for trouble. For an *operator*, it makes sense to keep the definition as closely associated with its class as possible. – David G Oct 24 '19 at 19:53
4

Because an operator needs to know details of the right-hand side of the expression in which is used, if it must access private data of the type which resides on that side, it needs to be friend with that class.

If you are trying to compare an int with a person, like in your example, choices are two:

  • you provide an implicit conversion from person to int so that < can use it without accessing any private field.
  • or you declare the operator as friend of person so that it can access x in the right-hand side of the comparison.
faressalem
  • 574
  • 6
  • 20
Jack
  • 131,802
  • 30
  • 241
  • 343
  • 3
    That would still be possible if only the friend declaration was inside the class definition, with the friend function definition kept outside of it. – Nicola Musatti Jul 07 '13 at 13:34
  • Thanks, But i didn't why we use friends, I asked why we are permitted to move the definition of friend methods inside our class definition. Is it not violating any things? If it is not, Why would we have friends in first place, We could simply define overloads as member functions ( I know the limitations of member functions ) but i am saying knowing this , why isn't compiler complaining that i haven't defined friend function outside a class definition since it doesnt need to be inside of it (because of the class parameter it has) – Hossein Jul 07 '13 at 13:34
  • I suggest you to take a look here: http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729 – Jack Jul 07 '13 at 13:36
  • @Hossein obviously it is not "violating any things". Otherwise you couldn't even ask the question, because it wouldn't compile. – juanchopanza Jul 07 '13 at 13:52
  • by violating i meant any thing such as good practice or the likes – Hossein Jul 07 '13 at 13:59
2

As Jack mentioned friend functions are required in places where access to private data is needed. There is also another purpose. This is related to types of inheritance. Only derived class and its friends can convert pointer to a private base to a derived type. So you might sometimes want to make some function a friend of derived class to allow this inside function body.

4pie0
  • 29,204
  • 9
  • 82
  • 118