我对模板类的显式实例化似乎不起作用
My explicit instantiation of template class seems doesn't work
我编写了一个简短的程序来测试模板类的显式实例化,如下所示:
#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 ) {... }
忘掉这个类,让它成为一个全局函数。而且您不需要显式的模板实例化。事实上,我唯一一次看到它的使用是当您在库中声明模板类并在另一个项目中使用时,您显然没有在这里这样做。
- 内部结构初始化不起作用 - C++
- 即使我正在.cpp文件中实例化一个伪对象,.cpp文件内模板函数的定义也不起作用
- 为什么显式模板实例化不起作用
- 函数模板中的显式模板专用化不起作用
- 为什么显式模板实例化不起作用?
- 完整的模板专用化不起作用:没有与指定类型匹配的函数模板"mysort2"实例 STLests
- 使用初始化列表的 POD 类型初始化不起作用
- 使用 fwrite/fread 对矩阵进行二进制(反)序列化不起作用
- POD变量的直接初始化不起作用,但当将变量推到向量上时,复制初始化起作用
- 函数专用化不起作用
- 窗口可防止多个实例代码不起作用
- 方法的简单专用化不起作用(C++)
- GCC 4.8.1 中的C++11:复制构造函数的列表初始化不起作用
- 模板部分专用化不起作用
- 为什么这种初始化不起作用
- 当比较sizeof(type) == constant时,c++模板特化不起作用
- boost::chrono::时间点类型的序列化不起作用
- std::list类型可变变量的boost序列化不起作用
- 嵌套结构的boost序列化不起作用
- 初始化不起作用