来自Lippman等人的C Primer第5版,第16.1.2节:
//forward declarations needed for friend declarations in Blob
template <typename> class BlobPtr;
template <typename> class Blob;
template <typename T> bool operator==(const Blob<T>&, const Blob<T>&)
template <typename T> class Blob {
friend class BlobPtr<T>;
friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
}
第一个问题:在线
friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
为什么< T>在==之后出现?为什么不简单写
friend bool operator==(const Blob<T>&, const Blob<T>&);
我添加了以下代码来定义operator ==并实例化类模板.它成功编译和链接:
template <typename T>
bool operator==(const Blob<T> &lhs, const Blob<T> &rhs) {return true;}
int main() {
Blob<int> a, b;
a == b;
}
如果我删除< T>在friend声明中跟随operator ==,我收到一个链接器错误:
Undefined symbols for architecture x86_64: "operator==(Blob<int> const&, Blob<int> const&)", referenced from: _main in partial_blob-3ccda9.o
显然,< T>以下运算符==是必要的,但为什么呢?
第二个问题:如果我想定义关系小于运算符 其功能我不明白
3)在课外定义运算符.
因此,我添加以下代码:
template <typename T> bool operator<(const Blob<T>&, const Blob<T>&);
template <typename T> class Blob {
//other members as before
friend bool operator<<T>(const Blob<T>&, const Blob<T>&);
}
bool operator<(const Blob<T>&, const Blob<T>&) {return true;}
int main() {
//other statements as before
a < b;
}
这会产生围绕运算符<< T>的编译错误,我认为因为编译器解释<<
friend bool operator<(const Blob<T>&, const Blob<T>&);
然后我得到一个类似于早期链接器错误的链接器错误==:
"operator<(Blob<int> const&, Blob<int> const&)", referenced from: _main in partial_blob-a85d5d.o
如何成功定义运算符
最佳答案
why is the
<T>
present after==
? Clearly the<T>
followingoperator==
is necessary, but why?
因为operator == in friend声明引用了函数模板,所以你必须明确指定它.否则将声明非模板函数,但稍后无法找到它的定义.它与调用(和实例化)函数模板的方式不同.
注意T可以省略但是<>仍然需要.如:
// refers to a full specialization of operator==
friend bool operator== <>(const Blob<T>&, const Blob<T>&);
另一种候选方法是在类声明中定义运算符,该运算符将是内联的,并且可以声明为非模板函数.如:
template <typename T> class Blob {
...
friend bool operator==(const Blob&, const Blob&) {
return ...;
}
}
This produces a compilation error around
operator<<T>
是的,正如你所说,它应该写成朋友bool操作符< < T>(…),或朋友bool运算符< <>(…),或者看看我对非模板功能朋友的建议.