I feel like this must be a duplicate, but I'm not seeing it at a cursory search.
Here's basically the problem. I want to keep a member private, but allow the usage of the namespace-level function (without ADL):
#include <utility>
namespace ns
{
template<class T>
decltype(std::declval<T const &>().bar()) foo(T const &v) { return v.bar(); }
}
template<class T>
class S
{
void bar() const { }
public:
friend constexpr decltype(std::declval<S const &>().bar()) ns::foo<S>(S const &c);
};
int main()
{
ns::foo(S<int>());
}
Unfortunately, this doesn't work due to an incomplete-type error:
member access into incomplete type 'const S<int>'
friend constexpr decltype(std::declval<S const &>().bar()) ns::foo<S>(S const &c);
^
How can I declare that ns::foo
is a friend of my class?
If you are ok to give more friendship, you might do
template <typename U>
friend decltype(std::declval<U const &>().bar()) ns::foo(U const &);
So all ns::foo<S<int>>
, ns::foo<S<char>>
and even ns::foo<OtherClass>
are friend
of S<int>
.