How do friend definitions work? Do they require a namespace-level declaration for accessibility?

Consider this example:

#include <type_traits>

class C { };

struct S {
  friend std::true_type f(C&) {
    return std::true_type();
  }
};
std::false_type f(C&);

int main() { C c; return decltype(f(c))::value; }

If I compile it, I get:

<source>:10:17: error: functions that differ only in their return type cannot be overloaded

However, if I comment out std::false_type f(C&);, I get:

<source>:12:35: error: use of undeclared identifier 'f'

How does this make sense? If the f inside S is undeclared, how can it possibly participate in overload resolution with the f outside it?! Conversely, if it’s declared, then why can’t I access it without declaring an f outside it? Could someone explain what’s going on?

Source: Windows Questions C++

LEAVE A COMMENT