我对模板类的显式实例化似乎不起作用

| 我编写了一个简短的程序来测试模板类的显式实例,如下所示:
#include <iostream>

template <class T>
struct less_than_comparable {
    friend bool operator>=(T const& a, T const& b) {
        return !(a < b);
    }
};

class Point {
    friend bool operator<(Point const& a, Point const& b) {
        return a.x_ < b.x_;
    }

public:
    Point(int x) : x_(x) {}

private:
    int x_;
};

template struct less_than_comparable<Point>; 
//Here I explicitly instantiate a template class expecting that 
//less_han_comparable<Point> would export opeartor>=() for class Point to the global
//namespace, and then the p1 >= p2 statement will work as expected.

int main() {
    using namespace std;

    Point p1(1), p2(2);
    cout << (p1 < p2) << endl;
    cout << (p1 >= p2) << endl; //But I have a compiler error here saying that 
                                //no match for ‘operator>=’ in ‘p1 >= p2’
}
我知道如果我从less_than_comparable继承Point,那么代码将通过编译。 但是我的问题是,如果我使用显式实例化,为什么它不起作用? 我使用在Ubuntu 10.04上运行的G ++ 4.4.5。 任何意见将不胜感激。谢谢。     
已邀请:
问题在于类类类型内部定义的好友函数不会注入到封闭的名称空间中。 您所指的原理称为“朋友名称注入”,但在当前的C ++标准中已被“ ADL”(参数相关查找,也称为Koenig查找)代替。 ADL检查与函数参数类型关联的所有名称空间以匹配函数。 在您的情况下,当您在
p1 >= p2
(即
operator>=(p1, p2);
)中呼叫
operator>=
时。 ADL在
Point
的命名空间中寻找匹配功能,但是
Point
没有此功能。 如果您从
less_than_comparable
继承
Point
,则
operator>=
成为
Point
命名空间的一部分,ADL可以在此处找到它。 您可以检查一下,此处没有朋友名称的注入。     
该代码无效,因为
Point
不是您定义
operator >=
的模板类。 如果要编译此代码,请在Point类中也定义
operator >=
。注意,
p1
p2
less_than_comparable
没有关系。 作为旁注,为什么要以
less_than_comparable
的名称为\“大于等于\”运算符定义运算符?     
显式实例化只是强制编译器在该翻译单元内编译特定模板的一种方法-它对名称的查找没有影响。 为了获得您想要的东西,您可以例如:
class Point : public less_than_comparable<Point> {
    
您的运算符> =是完全不同类型的成员函数,就编译器而言,它与Point无关。我想您想做的是:
template< T >
bool operator >= ( T const& a, T const& b ) {... }
忘记该类,而只是使其成为全局函数即可。而且您不需要显式的模板实例化。实际上,我唯一看到它使用的是您在库中声明了模板类并在另一个项目中使用了模板类,显然您在这里没有这样做。     

要回复问题请先登录注册