C类模板中的朋友比较和关系运算符

来自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> following operator== 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运算符< <>(…),或者看看我对非模板功能朋友的建议.

点赞