Note: I have seen all the similar questions on this website, but I still could not make this work.
I made a class for astronomical coordinates and I am trying to overload the << operator to store user input in the class. The two coordinates (right ascension and declination) are vectors of doubles.
When I call the parametrised constructor, I get the following two errors: "call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type" and "no match for call to '(coordinates) (std::vector&, std::vector&)'". It seems like I have to pass the vectors by reference, but I haven't managed to. How do I make it work?
Here is the code:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
class coordinates {
protected:
std::vector<double> right_ascension, declination;
public:
std::vector<double> zero_vector{(1,0)};
coordinates(): right_ascension{zero_vector}, declination{zero_vector} {} // Default constructor
coordinates(std::vector<double> ra, std::vector<double> dec) : right_ascension{ra}, declination{dec} {} // Paramterised constructor
~coordinates(){std::cout << "Calling coordinates destructor" << std::endl;}
friend std::istream& operator>>(std::istream &is, coordinates &coords);
};
std::istream& operator>>(std::istream &is, coordinates &coord){
// Read imput from string stream "1.1 2.2 3.3; 4.4 5.5 6.6"
std::string right_ascension;
double hh, mm, sec;
std::vector<double> ra, dec;
// Read data
std::stringstream ss("");
std::getline(is, right_ascension, ';');
ss.str("");
ss << right_ascension;
ss >> hh >> mm >> sec;
ra.push_back(hh);
ra.push_back(mm);
ra.push_back(sec);
is >> hh >> mm >> sec;
dec.push_back(hh);
dec.push_back(mm);
dec.push_back(sec);
coord(ra, dec); // Here I get the two errors I mentioned
return is;
}
int main() {
coordinates coords;
std::cout << "Input numbers (hh mm ss; hh ss mm)";
std::cin >> coords;
return 0;
}
CodePudding user response:
The correct syntax to create an object is:
coord = coordinates(ra, dec);
or
coord = coordinates{ra, dec};
(depending on your preferred style). This code constructs an object of type coordinates
and then assigns it to the coord
parameter.
CodePudding user response:
You can introduce a setter function for the coordinates
class:
// inside the coordinates class definition
void set_coordinates(const std::vector<double>& ra, const std::vector<double>& dec)
{
right_ascension = ra;
declination = dec;
}
And then call it on the reference to an instance of the class in the overloaded input operator:
// ...in the operator>> definition
coord.set_coordinates(ra, dec);
Also, note that you'd better off define your default ctor like this:
coordinates() = default;
Among the reasons is that it uses vector
's default ctor for the the right_ascension
and the declination
data members, which is what you want.