Reputation: 4082
I have a class like this:
namespace N
{
template<unsigned Mantissa, unsigned Fraction>
class C
{
//...
public:
friend C<Mantissa, Fraction> operator +(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right);
//...
};
}
And I've been trying to define that operator +
separately, but I can't get it to work.
I've tried:
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> N::operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
But I get "C2244 'operator +': unable to match function definition to an existing declaration"
I've tried:
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
But I get a linker error.
I've tried:
namespace N
{
template<unsigned Mantissa, unsigned Fraction>
C<Mantissa, Fraction> operator+(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right)
{
//...
}
}
But I get the same linker error.
I can't figure out what the issue is or how to resolve it.
The operator
has to be a friend
because it's accessing a private
field (I'd have to make the field public
otherwise, which I don't want to do if I can avoid it).
Upvotes: 2
Views: 289
Reputation: 172934
operator+
is declared as a non-template function inside the class definition, but you're trying to define it as a function template later, they don't match. If you want to make it a function template, you can
namespace N
{
// forward declaration of the class template
template<unsigned Mantissa, unsigned Fraction>
class C;
// forward declaration of the function template
template<unsigned Mantissa, unsigned Fraction>
C<Mantissa, Fraction> operator +(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right);
template<unsigned Mantissa, unsigned Fraction>
class C
{
//...
public:
// the instantiation of operator+ with template parameter of current Mantissa and Fraction becomes friend
friend C<Mantissa, Fraction> operator + <>(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right);
// ~~
//...
};
}
// definition of the function template
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> N::operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
If you want to make it a non-template function, then just define it inside the class definition:
namespace N
{
template<unsigned Mantissa, unsigned Fraction>
class C
{
//...
public:
// defined as non-template
friend C<Mantissa, Fraction> operator +(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right) {
//...
}
//...
};
}
Upvotes: 3