avatar
请教个C++的基础问题# JobHunting - 待字闺中
b*g
1
如何定义一个泛型的Point呢?比如Point的横坐标和纵坐标可以取int,double等等
我首先定义了这个:
template
class Point {
public:
T x;
T y;
Point() : x(0), y(0) {}
Point(T a, T b) : x(a), y(b) {}
};
结果接下来定义带有Point的函数的时候,提示“Argument list for class template
"Point" is missing”
请教下如何解决这个问题?谢谢。
avatar
l*8
2
你这段代码能编译吧。
贴贴完整的代码

【在 b*******g 的大作中提到】
: 如何定义一个泛型的Point呢?比如Point的横坐标和纵坐标可以取int,double等等
: 我首先定义了这个:
: template
: class Point {
: public:
: T x;
: T y;
: Point() : x(0), y(0) {}
: Point(T a, T b) : x(a), y(b) {}
: };

avatar
h*6
3
PointA; Point B;
avatar
r*l
4
你那个“带有Point的函数”怎么定义的呢?
avatar
b*g
5
完整代码已经贴出,麻烦帮忙找错,不胜感激。
avatar
c*r
6
错误在于你的Point 是class template, 不同于一般的class,你用的时候成了Point
type, 不是Point type. T需要你explicit或者编译器可以自动 deduct type.
下面是修改的代码:
#include
#include
#include
using namespace std;
template
class Point {
public:
T x;
T y;
Point() : x(0), y(0) {}
Point(T a, T b) : x(a), y(b) {}
};
template //如果没有这一行,编译器不知道T是什么type,所以这个函数必
须是
//function template
T distance(const Point& i) { //这里必须是const Point& , 可能因为
//priority_queue top 返回类型是这个吧
return i.x * i.x + i.y * i.y;
}
template //同样因为参数类型是Point, 这个也成为class template
struct compare_maxHeap {
bool operator()(Point& i, Point& j) {
return distance(i) < distance(j);
}
};
template //函数成为function template
vector > findkClosestPoints(vector > points, int k) {
vector > res(k);
int n = points.size();
if (n == 0) return res;
priority_queue,vector >,compare_maxHeap > maxHeap;
for (int i = 0; i < n; ++i) {
if (maxHeap.size() < k) {
maxHeap.push(points[i]);
}
else {
if (distance(points[i]) < distance(maxHeap.top())) {
maxHeap.pop();
maxHeap.push(points[i]);
}
}
}
for (int i = 0; i < k; ++i) {
res[k-1-i] = maxHeap.top();
maxHeap.pop();
}
return res;
}
int main()
{
//Find k closest points to origin
vector > points;
points.push_back(Point(0.1,0.2));
points.push_back(Point(0.2,0.3));
points.push_back(Point(7.1,2.2));
points.push_back(Point(6.1,0.2));
points.push_back(Point(5.1,0.2));
points.push_back(Point(4.1,0.2));
points.push_back(Point(0.3,0.4));
points.push_back(Point(0.5,0.4));
points.push_back(Point(2.1,0.2));
points.push_back(Point(3.1,0.2));
int k = 4;
vector > res = findkClosestPoints(points,k);
for (int i = 0; i < k; ++i) {
cout << res[i].x << ", " << res[i].y << endl;
}
return 0;
}
可以运行,不过不知道是不是你希望的结果:
0.1, 0.2
0.2, 0.3
0.3, 0.4
0.5, 0.4
avatar
f*4
7
Point改成下面定义,好处自己想
template
class Point {
public:
T x;
U y;
Point() : x(0), y(0) {}
Point(T a, U b) : x(a), y(b) {}
};
avatar
c*y
8
我觉得你需要的是boost::any,虽然我自己从来没有过这类需求。

【在 b*******g 的大作中提到】
: 如何定义一个泛型的Point呢?比如Point的横坐标和纵坐标可以取int,double等等
: 我首先定义了这个:
: template
: class Point {
: public:
: T x;
: T y;
: Point() : x(0), y(0) {}
: Point(T a, T b) : x(a), y(b) {}
: };

avatar
P*L
9
啥好处啊?
两个点的距离怎么算?

【在 f****4 的大作中提到】
: Point改成下面定义,好处自己想
: template
: class Point {
: public:
: T x;
: U y;
: Point() : x(0), y(0) {}
: Point(T a, U b) : x(a), y(b) {}
: };

avatar
c*r
10
当一个坐标值为整型,另一个为浮点型的时候可以吧?
不清楚什么特别的好处, 同问。

【在 P*******L 的大作中提到】
: 啥好处啊?
: 两个点的距离怎么算?

avatar
c*0
11
不能编译的原因就是point在被用到全局函数的时候没有说明type。修改的方法和你实
现class method的方法一样。
avatar
b*g
12
感谢前辈csiscoder经过实测的耐心细致的回复!给一千个赞!
运行了您修改的程序,bug free!
不过,还有个问题请求指点:
如果我将程序分别存在.h和.cpp文件里,为何有这样的报错呢:“error LNK2019:
unresolved external symbol”
--------------------------------------------------------------------
LeetCode.h内容为:
#include
#include
#include
template
class Point {
public:
T x;
T y;
Point() : x(0), y(0) {}
Point(T a, T b) : x(a), y(b) {}
};
//Find k closest points to origin
template
vector > findkClosestPoints(vector > points, int k);
---------------------------------------------------------------------
findkClosestPoints.cpp内容为:
#include "LeetCode.h"
template
T distance(const Point& i) {
return i.x*i.x+i.y*i.y;
}
template
struct compare_maxHeap {
bool operator()(Point& i, Point& j) {
return distance(i) < distance(j);
}
};
template
vector > kClosestPointsII(vector > points, int k) {
vector > res(k);
int n = points.size();
if (n == 0) return res;
priority_queue,vector >,compare_maxHeap > maxHeap;
for (int i = 0; i < n; ++i) {
if (maxHeap.size() < k) {
maxHeap.push(points[i]);
}
else {
if (distance(points[i]) < distance(maxHeap.top())) {
maxHeap.pop();
maxHeap.push(points[i]);
}
}
}
for (int i = 0; i < k; ++i) {
res[k-1-i] = maxHeap.top();
maxHeap.pop();
}
return res;
}
-----------------------------------------------------------------------------
main.cpp内容为:
#include "LeetCode.h"
int main()
{
//Find k closest points to origin
vector > points;
points.push_back(Point(0.1,0.2));
points.push_back(Point(0.2,0.3));
points.push_back(Point(7.1,2.2));
points.push_back(Point(6.1,0.2));
points.push_back(Point(5.1,0.2));
points.push_back(Point(4.1,0.2));
points.push_back(Point(0.3,0.4));
points.push_back(Point(0.5,0.4));
points.push_back(Point(2.1,0.2));
points.push_back(Point(3.1,0.2));
int k = 4;
vector > res = findkClosestPoints(points,k);
for (int i = 0; i < k; ++i) {
cout << res[i].x << ", " << res[i].y << endl;
}
}

T>

【在 c*******r 的大作中提到】
: 错误在于你的Point 是class template, 不同于一般的class,你用的时候成了Point
: type, 不是Point type. T需要你explicit或者编译器可以自动 deduct type.
: 下面是修改的代码:
: #include
: #include
: #include
: using namespace std;
: template
: class Point {
: public:

avatar
b*g
13
您这样定义可以满足横轴和纵轴对颗粒度的不同需求,更flexible些。
具体应用的场景有哪些呢?

【在 f****4 的大作中提到】
: Point改成下面定义,好处自己想
: template
: class Point {
: public:
: T x;
: U y;
: Point() : x(0), y(0) {}
: Point(T a, U b) : x(a), y(b) {}
: };

avatar
c*r
14
这是因为class template 的declaration 和implementation 要放到同一个源文件中
(STL 都这么干的)。 当然C++ template: the complete guide书中讲了另一种方法
,不过我没用过。 这个跟C++ 本身的compile 机制有关,很深,我自己也不是特别了
解底层怎么弄的。你可以上stackoverflow 网站随便搜搜,就有很多解释了,这里是
一个连接:
http://stackoverflow.com/questions/3749099/why-should-the-imple

【在 b*******g 的大作中提到】
: 感谢前辈csiscoder经过实测的耐心细致的回复!给一千个赞!
: 运行了您修改的程序,bug free!
: 不过,还有个问题请求指点:
: 如果我将程序分别存在.h和.cpp文件里,为何有这样的报错呢:“error LNK2019:
: unresolved external symbol”
: --------------------------------------------------------------------
: LeetCode.h内容为:
: #include
: #include
: #include

avatar
c*0
15
你在client里只include了头文件,因此头文件会根据你定的type实现。而source code
没有根据你的type对应实现,因为你没有把他们写在一起。这样当你link的时候就找不
到相应的实现了。
如果没有template,是可以link的,因为实现的代码是固定的
avatar
c*0
16
你可以在template的头文件最后加上
#include 模版的source code (.c)
或者在main上面同时include 头文件和对应的.c

【在 b*******g 的大作中提到】
: 您这样定义可以满足横轴和纵轴对颗粒度的不同需求,更flexible些。
: 具体应用的场景有哪些呢?

avatar
b*g
17
多谢,试了第二个方法,很奏效。

【在 c***0 的大作中提到】
: 你可以在template的头文件最后加上
: #include 模版的source code (.c)
: 或者在main上面同时include 头文件和对应的.c

avatar
f*4
18
定义成class T, class U,更灵活&类型安全
对2个及2个以上参数没有特殊类型要求的地方都可以用
(就是有特殊要求的话,也可以考虑是否能用template specialization来解决)
相当于free money on the table

【在 b*******g 的大作中提到】
: 您这样定义可以满足横轴和纵轴对颗粒度的不同需求,更flexible些。
: 具体应用的场景有哪些呢?

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。