'util.h'中定义的以下代码编译和链接。但是,当我将运算符重载的实现移动到'util.cc'时,链接器无法解析符号。这是否可以做到,或者由于模板的性质而无法做到这一点?
谢谢,
util.h
template<class T>
struct Rect {
T x, y, w, h;
friend bool operator ==(const Rect<T> &a, const Rect<T> &b) {
return (a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h);
}
friend bool operator !=(const Rect<T> &a, const Rect<T> &b) {
return !(a == b);
}
};
util.h
template<class T>
struct Rect {
T x, y, w, h;
friend bool operator ==(const Rect<T> &a, const Rect<T> &b);
friend bool operator !=(const Rect<T> &a, const Rect<T> &b);
};
util.cc
template<class T>
bool operator ==(const Rect<T> &a, const Rect<T> &b)
{
return (a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h);
}
template<class T>
bool operator !=(const Rect<T> &a, const Rect<T> &b)
{
return !(a == b);
}
答案 0 :(得分:6)
对于@AndyProwl link中解释的原因,您的实际问题的答案是否定的,即使您在标题util.h
中包含运算符定义,答案仍然是否定的。
原因是这些运算符实际上是非模板函数,它们注入到它们被定义为侧的类的封闭范围内 - 效果类模板实例化。换句话说,这个类模板
template<class T>
struct Rect {
T x, y, w, h;
friend bool operator ==(const Rect<T> &a, const Rect<T> &b);
friend bool operator !=(const Rect<T> &a, const Rect<T> &b);
};
为每种类型生成以下两个非模板函数T
bool operator ==(const Rect<T> &a, const Rect<T> &b);
bool operator !=(const Rect<T> &a, const Rect<T> &b);
如果您还定义了功能模板
template<class T>
bool operator ==(const Rect<T> &a, const Rect<T> &b)
{
return (a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h);
}
template<class T>
bool operator !=(const Rect<T> &a, const Rect<T> &b)
{
return !(a == b);
}
并在你的代码中调用它们,然后名称查找和参数推导继续没有困难,但函数重载解析将以非模板类内友元函数打破的平局结束。但是,如果未定义这些内容,您的程序将无法链接。
有两个转义:在类中定义运算符(如您已提供的那样)或(再次由@AndyProwl提及)使用此peculair语法与类中的通用运算符模板建立联系
// forward declarations
template<typename T> struct Rect;
template<typename T> bool operator==(const Rect<T>&, const Rect<T>&);
template<typename T> bool operator!=(const Rect<T>&, const Rect<T>&);
template<class T>
struct Rect {
T x, y, w, h;
// friend of operator templates
friend bool operator == <>(const Rect<T> &a, const Rect<T> &b);
friend bool operator != <>(const Rect<T> &a, const Rect<T> &b);
};
// definitions of operator templates follow
请注意,交友模板是一件棘手的事情,正如Herb Sutter在old column中所解释的那样。