This is not a duplicate. I've checked lots of answers, the FAQ and else. Nothing of that told me news. Here is the simplified code. It's the minimum to get and explain the error.
/*** Polynomial.hpp ********************************************************/
namespace Modulus
{
// Forward declaration of the types and non-inline template friend functions.
template <typename T>
class Polynomial;
template <typename T>
Polynomial<T> operator +
(Polynomial<T> const & p,
Polynomial<T> const & q);
}
namespace Modulus
{
template <typename T>
class Polynomial
{
public:
Polynomial() { }
// [!] when you comment this in, you get the error.
//Polynomial operator + () const { return *this; }
friend Polynomial operator + <> (Polynomial const & p,
Polynomial const & q);
};
} // namespace
// Template: include .cpp file.
//#include "Polynomial.cpp"
///^ It is commented out, for compiling in one file.
/*** Polynomial.cpp ********************************************************/
namespace Modulus
{
template <typename T>
Polynomial<T>
operator + (Polynomial<T> const & p,
Polynomial<T> const & q)
{
return Polynomial<T>();
}
} // namespace
/*** main.cpp **************************************************************/
//#include "Polynomial.hpp"
using namespace Modulus;
int main()
{
Polynomial<int> p;
p + p;
return 0;
}
When I comment the line under [!]
in, the error I get is friends can only be classes or functions
(Clang++) or declaration of ‘operator+’ as non-function
(g++).
For me, it seems the compilers mistake the two operators. As far as I've learned the operator overloading stuff, the unary and binary operators are completely independent and can be uniquely distinguished by their number of arguments.
So why does the error occur? Making the unary operator a friend using the standard practice, makes the code compile fine on both compilers.
When you declare something in a scope, it hides delcarations of the same name in any wider scope. Here, the declaration of the member operator+
hides that of the non-member. So the friend
declaration refers to the member, not the non-member, hence the error.
You'll need to qualify the name if you want to refer to both in the same scope:
Polynomial operator + () const { return *this; }
friend Polynomial Modulus::operator + <> (Polynomial const & p, Polynomial const & q);
^^^^^^^^^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With