I an new to class templates. I am trying to define class Point. Right now Point only has member coords to store coordinates in list. I am trying to make class that would work with any dimensional space. For 1 dimensional space, coords list should have size of 1. For 2D coords.size() should be 2 and so on. For this I tried to use template, but I did something wrong, and I dont know what.
background info: Previously, I had class Point2 for point 2D point (x, y). And Point3 for 3D point (x,y,z). Now need to generalize it so it woul work with any number of dimensions.
D:\Dropbox\cpp\point.h|14|error: 'n' is not a type|
D:\Dropbox\cpp\test.cpp||In function 'int main(int, char**)':|
D:\Dropbox\cpp\test.cpp|10|error: 'v1.Point<n>::coords<2u>' does not have class type|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
what do I need to do that cout << v1.coords.size() << endl; would print 2 (test.cpp should not be changed)? How do I use that n inside class?
#ifndef POINT_H
#define POINT_H
//#include <iostream> //not being used
#include <list>
//using std::ostream; //never do `using' in headers
template <unsignedshort n>
class Point {
public:
std::list<float> coords = std::list<float>(n); //initialization
Point() = default; //c++11 The default constructor is explicitly stated.
Point(std::list<float> p);
//float distanceFrom (std::list<float> p); //it does not match with your definition
float distanceFrom (Point p);
};
//still in point.h, you can't separate template definitions
#include <math.h> /* sqrt */
#include <list>
template <unsignedshort n> //Point is a template
Point<n>/*here too, need to especify the template parameter*/::Point(std::list<float> arg)
{
coords.assign (arg.begin(), arg.end());
}
template <unsignedshort n> //Point is a template
float Point<n>::distanceFrom (Point p) { //no need to especify, but its argument has the same template parameter (Point<n>)
//return sqrt (pow(x-p.x,2.0) + pow(y-p.y,2.0));
return 0.0;
}
#endif
> store coordinates in list.
that's like the worst container that you may chose.
consider std::{array,valarray,vector} where you also have random access.
template <unsignedshort n>
Point<n>::Point(std::list<float> arg)
{
coords.assign (arg.begin(), arg.end()); //you need to make sure that arg.size()==n
}
Point<2> v2 { list<float>{} }; //v2.coords is empty instead of having 2 elements
If I use your code, everything works but as soon as I use separate header and code files, it breaks.
That's because when dealing with templates the definition and implementation must be in the same compilation unit. This quite often leads to header only implementations, or including the source in the header.
Ok. I did not know that. It came as a little surprise to me because it is actually a task from C++ course where we were told to have separate .cpp and .h files. And that's why I told above not to change test.cpp... test.cpp was actually provided by lectures and we are supposed to write the rest of the code so that test.cpp compiles as compiles as they have provided it. All that I did for this topic was removing code from the end to make it shorter.
My intention is just to get to know it a little bit before course starts and solve few simpler problems in advance that it would be easier to follow.