Ваша первая декларация объявляет, что foo
- это имя шаблона. функция с именем foo
отсутствует. Функции, сгенерированные из шаблона с именем foo
, будут иметь имена наподобие foo<T, N>
, где T
- это имя типа, а N
- целое число.
Ваша декларация друга объявляет, что должен быть foo
который является именем функции. Это не совпадает с foo
, который является именем шаблона.
Если вы хотите объявить, что Bar
разрешит любое создание шаблона foo
формы foo<Bar, *>
чтобы получить доступ к его частным лицам ... ну, вы не можете. Вы можете объявить друга всем, что генерирует шаблон:
template<typename T, std::size_t N>
friend auto foo( T const(&)[N] );
Вы можете объявить дружбу с конкретным экземпляром шаблона:
friend auto foo<Bar, 20>( Bar const(&)[20] );
Но вы не можете объявить его другомтолько некоторые шаблонных функций. Если вы попробуете что-то вроде этого:
template<std::size_t N>
friend auto foo(Bar const(&init)[N]);
Вы обнаружите, что ваш оригинальный foo
не сможет получить к нему доступ. Это относится к другому шаблону из шаблона foo
, так как он принимает другие параметры.