Search code examples
c++templatesfriend

How to friend a function template inside a class template?


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?


Solution

  • 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 &);
    

    Demo

    So all ns::foo<S<int>>, ns::foo<S<char>> and even ns::foo<OtherClass> are friend of S<int>.