Any standard on how to define operator overloading type

Is there any standard or guidelines which say when to declare an operator overloading function as friend and when as in class member?


Thanks
Last edited on
Basically operators not declared as friend cannot take more than one parameter, this is because the first argument for member functions is implicitly this. So if you need that extra parameter for an operator, you need to make use of friends.

In essence, all operators can be defined as friends, but not all can be defined as members of the same class.
http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729

http://stackoverflow.com/questions/4421706/operator-overloading
Last edited on
Basically operators not declared as friend cannot take more than one parameter,


This only holds if two different objects are passed in the parameters, i am guessing?
Not always the case example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
#include <type_traits>

class Num {
    unsigned long long value;
public:
    Num(unsigned long long value) : value(value){}
    template <typename T, typename std::enable_if<std::is_convertible<T,
                                                unsigned long long>::value,int>::type = 0>
    Num& operator += (const T& other) {
        value += other;
        return *this;
    }
    
    operator unsigned long long(void) const {
        return value;
    }
};


int main() {
    Num t = 10;
    
    int add = 10;
    t += add;
    
    Num g = 90;
    t += g;
    
    std::cout << t << std::endl;
    
    return 0;
}


As you can see, the overloaded += operator is not a friend operator but works for any Num type and any integral type. If you recall, the implicit parameter of const Num* this is passed in as the first parameter for member operators, so this function does infact take 2 different objects as parameter, but the this parameter is passed implicitly

So the types of objects does not determine what you can pass in, another example of this is std::hash<T>::operator()(const T&);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <functional>
#include <string>
 
struct S
{
    std::string first_name;
    std::string last_name;
};
 
namespace std
{
    template<>
    struct hash<S>
    {
        typedef S argument_type;
        typedef std::size_t result_type;
 
        result_type operator()(argument_type const& s) const
        {
            result_type const h1 ( std::hash<std::string>()(s.first_name) );
            result_type const h2 ( std::hash<std::string>()(s.last_name) );
            return h1 ^ (h2 << 1);
        }
    };
}
 
int main()
{
    S s;
    s.first_name = "Bender";
    s.last_name =  "Rodriguez";
    std::hash<S> hash_fn;
 
    std::cout << "hash(s) = " << hash_fn(s) << "\n";
}

The above taken from http://en.cppreference.com/w/cpp/utility/hash

Class operators can be overridden to take any type as a parameter, but there can only be one of such type.
Last edited on
> Is there any standard or guidelines which say when to declare
> an operator overloading function as friend and when as in class member?

>> Is there any standard or guidelines which say when to declare
>> any operator overloading function as friend and when as in class member?

I'll start with the punchline: If you're writing a function that can be implemented as either a member or as a
non-friend non-member, you should prefer to implement it as a non-member function. That decision increases class encapsulation. When you think encapsulation, you should think non-member functions. - Scott Meyers
http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197?pgno=1

To the majority, this was something new at the time it appeared in 2000.
Fifteen years later, this is now part of maintream C++ knowledge.
Last edited on
thanks
Topic archived. No new replies allowed.