Int*_*rca 5 c++ templates operator-overloading friend
'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);
}
};
Run Code Online (Sandbox Code Playgroud)
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);
};
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
对于@AndyProwl 链接中解释的原因,您的实际问题的答案是否定的,即使您在标题中包含运算符定义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);
};
Run Code Online (Sandbox Code Playgroud)
为每种类型生成以下两个非模板函数T
bool operator ==(const Rect<T> &a, const Rect<T> &b);
bool operator !=(const Rect<T> &a, const Rect<T> &b);
Run Code Online (Sandbox Code Playgroud)
如果您还定义了函数模板
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);
}
Run Code Online (Sandbox Code Playgroud)
并呼吁他们在你的代码,然后将其命名查询和参数推导进行无困难,但函数重载决议将在领带是由非模板类友元函数断头.但是,如果没有定义这些,您的程序将无法链接.
有两个转义:在类中定义运算符(如您已提供的那样)或(再次由@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
Run Code Online (Sandbox Code Playgroud)
请注意,与Herb Sutter的旧专栏中解释说,交友模板是一项棘手的工作.