How to solve "[Warning] declares a non-template function" when cPP overloads input and output functions?

I"m working on a cPP template problem, described as follows:
"create a template for the Array class. This template allows the Array object to instantiate a specific element type that specifies the number of elements at compile time. "
and the compilation always fails when I overload the input and output stream functions.

the compiler shows:
[Warning] friend declaration "std::istream& operator > > (std::istream&, Array < T, n > &)" declares a non-template function [- Wnon-template-friend]
[Warning] friend declaration "std::ostream& operator < < (std::ostream&, const Array < T, n > &)" declares a non-template function [- Wnon-template-friend]

the code is as follows:

-sharpinclude<iostream>
using namespace std;
template<class T,int n>
class Array
{
    private:
        T p[n];
        static int count;
    public:
        friend istream & operator>> (istream & in, Array<T,n>& a);
        friend ostream & operator << (ostream & out,const Array<T,n>& a);
        int getSize()
        {
            return n;
        }
        static int getArrayCount()
        {
            return count;
        }
};
template<class T,int n>
istream & operator >> (istream & in,const Array<T,n>& a)
{
    for(int i=0;i<n;iPP)
    {
        in>>a.p[i];
    }
    a.countPP;
    return in;
}
template<class T,int n>
ostream & operator << (ostream & out,const Array<T,n>& a)
{
    for(int i=0;i<n;iPP)
    {
        out<<a.p[i]<<" ";
    }
    return out;
}

paste the main function here:

int main()
{
    Array< int, 5 > intArray1;
    cin >> intArray1;
    Array< int, 5 > intArray2;
    cin >> intArray2;
    Array< float, 5 > floatArray;
    cin >> floatArray;
    cout << "\nIntArray1 contains " << intArray1.getSize() << " Elements.\n";
    cout << "The values in intArray are:\n";
    cout << intArray1;
    cout << "\nIntArray2 contains " << intArray2.getSize() << " Elements.\n";
    cout << "The values in intArray are:\n";
    cout << intArray2;
    cout << "\nDoubleArray contains " << floatArray.getSize() << " Elements.\n";
    cout << "The values in the doubleArray are:\n";
    cout << floatArray;
    cout << "\nThere are " << Array<int,5>::getArrayCount() << " Array<int,5> objects.\n";
    cout << "\nThere are " << Array<float,5>::getArrayCount() << " Array<float,5> objects.\n";
    return 0;
}

I have searched the Internet for a long time and tried a lot of solutions, but neither adding < > after > > in the line
istream & operator > (istream & in,const Array < TMagazn > & a)
nor defining input and output functions in the class does not work.
if defined in a class, the following error appears:
undefined reference to `Array < float, 5 >:: count"
[Error] ld returned 1 exit status

if you add < > after > >, the following error appears:
[Error] template-id "operator > < >" in declaration of primary template

so it"s hard to walk now, and I don"t have a clue at all.
I also hope that all the great gods can answer my doubts and explain why the above three mistakes occurred.
Thank you very much!

CPP
Mar.06,2021

@ felix Boss has fully answered OP your question. Make a slight supplement:

  1. declaring it as a friend of a class template destroys the encapsulation of the class, for example, the friend function of X < int > foo is visible to all X < T >. Then it means that X < int > indirectly and unreasonably obtains all the information of X < T > (such as its private member). Therefore, it is not recommended, for example, the following code can be overcompiled.
-sharpinclude<iostream>
using namespace std;
template<typename T>
class A
{
private:
    T x;
    void setter(T y)
    {
        x = y;
    }
public:
    explicit A(T a) : x(a) {}
    template<typename U>
    friend void foo(A<U> a);
};
A<int> x(7);
template<typename U>
void foo(A<U> a)
{
    x.x = 2;
}
int main()
{
    A<int> a(7);
    A<float> b(1.1);
    foo(b);
}
  1. there is a third way, which is to use the pre-declaration method, as detailed in the following code.
  2. first static member variable count needs to be defined outside the class starting from cPP1z may need to be changed to first the static member variable count of non-constexpr needs to be defined outside the class. see http://eel.is/cPPdraft/depr.s. for details. Demo can try it out by writing an odr-use function.
  3. there is something wrong with your const.
template <class T>
class X {
  template <class U>
  friend void foo(U);
};
Menu