C++ 如何定义在命名空间中的模板上声明的友元运算符?
我有一门课是这样的:C++ 如何定义在命名空间中的模板上声明的友元运算符?,c++,templates,friend,C++,Templates,Friend,我有一门课是这样的: namespace N { template<unsigned Mantissa, unsigned Fraction> class C { //... public: friend C<Mantissa, Fraction> operator +(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & ri
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);
//...
};
}
但我得到“C2244‘运算符+”:无法将函数定义与现有声明匹配”
我试过:
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> N::operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
namespace N
{
template<unsigned Mantissa, unsigned Fraction>
C<Mantissa, Fraction> operator+(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right)
{
//...
}
}
模板
N::C运算符+(常数N::C和左、常数N::C和右)
{
//...
}
但我得到一个链接器错误
我试过:
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> N::operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
template<unsigned Mantissa, unsigned Fraction>
N::C<Mantissa, Fraction> operator+(const N::C<Mantissa, Fraction> & left, const N::C<Mantissa, Fraction> & right)
{
//...
}
namespace N
{
template<unsigned Mantissa, unsigned Fraction>
C<Mantissa, Fraction> operator+(const C<Mantissa, Fraction> & left, const C<Mantissa, Fraction> & right)
{
//...
}
}
名称空间N
{
模板
C运算符+(常数C和左、常数C和右)
{
//...
}
}
但我得到了相同的链接器错误
我不知道问题是什么,也不知道如何解决。
操作符
必须是朋友
,因为它正在访问一个私有
字段(我必须将该字段公开
,否则,如果可以避免的话,我不想这样做)。操作符+
在类定义中声明为非模板函数,但您稍后试图将其定义为函数模板,它们不匹配。如果您想使其成为函数模板,可以
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)
{
//...
}
名称空间N
{
//类模板的转发声明
模板
丙级;;
//函数模板的前向声明
模板
C运算符+(常数C和左、常数C和右);
模板
C类
{
//...
公众:
//模板参数为当前尾数和分数的运算符+的实例化成为朋友
友元C运算符+(常数C和左、常数C和右);
// ~~
//...
};
}
//函数模板的定义
模板
N::cn::operator+(常数N::C和left,常数N::C和right)
{
//...
}
如果要使其成为非模板函数,则只需在类定义中定义它:
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) {
//...
}
//...
};
}
名称空间N
{
模板
C类
{
//...
公众:
//定义为非模板
友元C运算符+(常数C和左、常数C和右){
//...
}
//...
};
}
为什么在N::C
中使用T
???你的模板是template
@NathanOliver我在打问题时犯了一个小错误。它实际上在实际代码中使用了
,现在将问题调整为匹配。是否必须在类定义中定义非模板运算符?(到目前为止,我只是在类定义中声明函数并在以后定义它们。)@Pharap我假设您可以像处理模板类的任何其他成员函数一样处理template N::C N::C::operator+…
。@cdhowie将其作为成员函数的问题是,我必须处理操作符的问题。@Pharap顺便说一下,在C
的定义中,C
成为特定实例化的别名。Sofriend C操作符+(常数C&左,常数C&右)代码>可以简化为友元C操作符+(常数C和左、常数C和右)
.AFAIK不可能在使用class template参数的主体之外以任何方式定义模板类的友元函数。这只是一个奇怪的边缘案例,允许朋友函数与成员函数一起实例化,但我知道没有语法可以让您在主体之外定义它。如果有人认为这是可能的,我希望看到一个反例。