Consider the following program:
#include <iostream>
template<typename T> void f1(T& v)
{
std::cout << "f1: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T& v) requires requires (T& v) { v.g(); }
{
std::cout << "f2: can call g" << std::endl;
v.g();
}
template<typename T> void f2(T&) requires (!requires (T& v) { v.g(); })
{
std::cout << "f2: cannot call g" << std::endl;
}
class A
{
public: // if commented out, f2 will not call g anymore
void g()
{
std::cout << "g called" << std::endl;
}
template<typename T> friend void f1(T& v);
template<typename T> friend void f2(T& v);
};
class B
{
};
int main()
{
std::cout << "A" << std::endl;
A a{};
f1(a);
f2(a);
std::cout << "B" << std::endl;
B b{};
f2(b);
return 0;
}
The function g might exists in a class or not. If it does (like for A), the function f2 should call it, if not (like for B) it shouldn't. This distinction is made via the requires clause.
I befriended f2 in A so it should be able to call g even if it is private (in general befriending works fine, see f1). However, the requires seems to ignore that the function is befriended and thus, when making g private in A, g is not called anymore.
Why is this? Is there a workaround for this, i.e. conditioning on whether a function can be called, even if it's private (but befriended)? Maybe even using old school std::enable_if?