'Does member function like operator<< , operator* need ADL to work?

I have a code snippet (Hypothetically):

#include <iostream>

struct Pirate {
 void song_name() {
  std::cout << "Bink's Sake\n";
 }

 Pirate& operator*(Pirate const& other) {
  // do something
  return *this;
 }
};

int main() {
 Pirate p1{} p2{};
 p1.song_name(); // does this use qualified or unqualifed name lookup?
 
 p1 * p2;

 std::cout << 5;
 std::cout << 'a';
}

Does p1 * p2 use qualified name lookup or unqualified name lookup or ADL?

std::cout << 5 transforms into std::cout.operator<<(5); std::cout << 'a' transforms into std::operator<<(std::cout, 'a');

Does member functions require ADL to work? Does the above two statments use qualified or unqualifed name lookup or ADL?

Thanks



Solution 1:[1]

The operators lookup non-static member functions like

std::cout.operator<<(5);

but also non-member functions via unqualified lookup and ADL if they have a non-member variant. All of these together form the overload set.

For this to work correctly non-member variants should be found via ADL, i.e. placed inside the namespace of the class for which they are overloading the operator. E.g. for overloading operator<< for your own classes you cannot use a member version, because the first argument is probably supposed to be anything derived from std::ostream. Then ADL on the non-member variant is the only way to make it work everywhere.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user17732522