For some time I\'ve been designing my class interfaces to be minimal, preferring namespace-wrapped non-member functions over member functions. Essentially following Scott Meyer
Prefer non-member non-friend functions for encapsulation UNLESS you want implicit conversions to work for class templates non-member functions (in which case you better make them friend functions):
That is, if you have a class template type
:
template
struct type {
void friend foo(type a) {}
};
and a type implicitly convertible to type
, e.g.:
template
struct convertible_to_type {
operator type() { }
};
The following works as expected:
auto t = convertible_to_type{};
foo(t); // t is converted to type
However, if you make foo
a non-friend function:
template
void foo(type a) {}
then the following doesn't work:
auto t = convertible_to_type{};
foo(t); // FAILS: cannot deduce type T for type
Since you cannot deduce T
then the function foo
is removed from the overload resolution set, that is: no function is found, which means that the implicit conversion does not trigger.