Ayxan Haqverdili
's answer seems to be cleanest possible, and abides by the ISO. However, pre-gcc 11.0
and pre-clang 8.0
appear to have bugs that cause this to fail.
Luckily in this case there's an alternative that uses argument-dependent lookup:
#include <iostream>
class Foo
{
friend int Bar (Foo)
{
return 13;
}
friend int RedirectToBar (Foo);
public:
int Bar (Foo)
{
return RedirectToBar(Foo());
}
};
int RedirectToBar (Foo)
{
return Bar(Foo());
}
int main ()
{
std::cout << Foo().Bar(Foo()) << std::endl;
}
Live demo
Keep in mind that this only works because some of the arguments to the function are an associated class.
If that's not the case and you really want to keep this design and really need compatibility with older compilers, then we can add in a dummy associated class without breaking the interface by adding it as a default parameter:
#include <iostream>
int RedirectToBar ();
class Foo
{
struct Key {};
friend int Bar (Key = Key())
{
return 13;
}
friend int RedirectToBar ();
public:
int Bar ()
{
return RedirectToBar();
}
};
int RedirectToBar ()
{
return Bar(Foo::Key());
}
int main ()
{
std::cout << Foo().Bar() << std::endl;
}
Live demo
However, it's important to add that all of this is a big code smell. Although I don't know the real-world problem of the OP, this seems like a terrible hack to get around bad design choices.