Search code examples
c++templatesc++17friend

template<class T, int N> void h(T const(&)[N]); as friend function


There is a freestanding function (non-member one) defined as:

template<class T, std::size_t N> 
auto foo(T const(&init)[N]) { /* ... */ }

foo() is intended to deduce the N (array size)

Additionally, within the same namespace there is a class defined as:

class Bar {

friend auto foo( Bar const(&)[/* ??? */] ); /* <-------- The goal to make it right */

private:
    Bar( void ) { /* ... */ }
};

My problem is I am not successful yet to declare the foo() as friend to Bar class so that it can access the private members.

In the foo() declaration, there is std::size_t N template parameter. But how to make the friendship of all N values?

Many thanks in advance for anyone willing to help.

Martin


Solution

  • Your first declaration declares that foo is the name of a template. There is no function named foo. The functions generated from the template named foo will have names like foo<T, N>, where T is a type name and N is an integer.

    Your friend declaration declares that there should be a foo which is the name of a function. That doesn't match up with the foo which is the name of a template.

    If you want to declare that Bar will allow any instantiation of the foo template of the form foo<Bar, *> to access its privates... well, you can't. You can declare a friend of anything the template generates:

    template<typename T, std::size_t N>
    friend auto foo( T const(&)[N] );
    

    You can declare friendship with of a specific template instantiation:

    friend auto foo<Bar, 20>( Bar const(&)[20] );
    

    But you can't declare it a friend of only some of the template generated functions. If you tried something like this:

    template<std::size_t N>
    friend auto foo(Bar const(&init)[N]);
    

    You would find that your original foo wouldn't be able to access it. This is referring to a different template from the foo template, as it takes different parameters.