我的代码出了什么问题?
template<int E, int F>
class Float
{
friend Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
};
G只是警告:
float.h:7:警告:朋友声明’浮动< E,F> operator(const Float< E,F>&,const Float< E,F>&)’声明一个非模板函数
float.h:7:警告:(如果这不是您的意图,请确保已声明函数模板并在此处添加<>之后的函数名称)-Wno-non-template-friend禁用此警告
我试图添加<>在警告说明中提到的函数名称之后,但g给了我一个错误.
我用clang编译代码,很好,没有任何警告.
解决方法:
这只是对该语言棘手方面的警告.声明友元函数时,它不是声明所在类的成员.为方便起见,可以在那里定义它,但它实际上属于命名空间.
在类模板中声明不是模板的友元函数仍然在命名空间中声明非模板函数.它既不是类的成员,也不是模板.但是,它是由类模板生成的.
从模板生成非模板函数有点模糊.例如,您不能在类块之外添加该函数的声明.因此,您必须在类块中定义它,这是有道理的,因为类模板将生成它.
关于朋友的另一个棘手的事情是,Float {}类中的声明不会在命名空间中声明该函数.您只能通过依赖于参数的含义重载决策来找到它,即指定一个参数具有Float类型(或引用或指针).这对于运算符来说不是问题,因为它可能会过载,并且除了用户定义的类型之外永远不会被调用.
有关潜在问题的示例,请假设您有一个转换构造函数Float :: Float(Bignum const&).但是Bignum没有经营者. (对不起,人为的例子.)你想依靠运算符(Float const&,Float const&)来增加Bignum.现在my_bignum 3将无法编译,因为两个操作数都不是Float,因此无法找到友元函数.
可能你没有什么可担心的,只要有问题的功能是运算符.
或者,您也可以将朋友更改为模板.在这种情况下,它必须在class {}块之外定义,并在它之前声明,而不是在内部声明和定义.
template<int E, int F> // now this is a template!
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
template<int E, int F>
class Float
{
// deduce arguments E and F - this names operator+< E, F >.
friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};