Hi,

I'm developing a C++ application, but I've not programmed in C++ for a while, so I am a little rusty.

I have been trying to compile just a test application to make sure these couple of classes work properly.

This is on Windows Vista with Cygwin, using gcc 3.4.4. I know that's an old version, but I also tried on my CentOS server with gcc 4.1.2.

Here is the linker error:

Code:
/cygdrive/c/Users/Brandon/AppData/Local/Temp/ccpwAbAo.o:star_trek.cpp:(.text+0x496): undefined reference to `physics::cartesian_coordinate_system::point<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::astronomical::light_second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void> >::point(boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::astronomical::light_second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, double>, boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::astronomical::light_second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, double>, boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::astronomical::light_second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> >, void>, double>)'
collect2: ld returned 1 exit status
Here is some of my code. I don't really know how much to show, but I've taken out some irrelevant code from main().

Main file:

Code:
#include <boost/typeof/typeof.hpp>
#include <boost/units/io.hpp>
#include <boost/units/systems/si.hpp>
#include <boost/units/units/astronomical.hpp>
#include <boost/units/units/time.hpp>
#include <galaxy.hpp>
#include <iostream>
#include <physics/cartesian_coordinate_system/point.hpp>

int main()
{
using namespace boost::units;
using namespace std;
namespace cart = physics::cartesian_coordinate_system;

quantity<astronomical::light_second_unit> x(2.0 * astronomical::light_seconds);
quantity<astronomical::light_second_unit> y(5.0 * astronomical::light_seconds);
quantity<astronomical::light_second_unit> z(4.0 * astronomical::light_seconds);
cart::point<astronomical::light_second_unit> p(x, y, z);
cout << p.to_string() << endl;

return 0;
}
physics/point.hpp:

Code:
#ifndef PHYSICS_POINT_H
#define PHYSICS_POINT_H

#include <boost/tr1/memory.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/unit.hpp>
#include <string>

namespace physics
{

template<class Unit>
class point
{
public:
virtual boost::units::quantity<Unit> distance_from(point const*) const;
/*virtual std::tr1::shared_ptr<physics::cartesian_coordinate_system::point<Unit>>
to_cartesian() = 0;*/
/*virtual std::tr1::shared_ptr<physics::cylindrical_coordinate_system::point> to_cylindrical() = 0;*/
virtual std::string to_string() const = 0;
virtual std::string to_string(Unit const&) const = 0;
/*virtual std::tr1::shared_ptr<physics::spherical_coordinate_system::point>
to_spherical() = 0;*/
}; // class point

template<class Unit>
boost::units::quantity<Unit>
point<Unit>::distance_from(point<Unit> const* point) const
{
return this->to_cartesian()->distance_from(point);
} // distance_from

} // namespace physics

#endif // PHYSICS_POINT_H
physics/cartesian_coordinate_system/point.hpp:

Code:
#ifndef PHYSICS_CARTESIAN_COORDINATE_SYSTEM_POINT_HPP
#define PHYSICS_CARTESIAN_COORDINATE_SYSTEM_POINT_HPP

#include <boost/typeof/typeof.hpp>
#include <boost/units/cmath.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/unit.hpp>
#include <sstream>
#include <physics/point.hpp>

namespace physics
{
namespace cartesian_coordinate_system
{
template <class Unit>
class point : public physics::point<Unit>
{
public:
point(boost::units::quantity<Unit>, boost::units::quantity<Unit>, boost::units::quantity<Unit>);
boost::units::quantity<Unit> distance_from(point const*) const;
boost::units::quantity<Unit> get_x() { return this->x_; }
boost::units::quantity<Unit> get_y() { return this->y_; }
boost::units::quantity<Unit> get_z() { return this->z_; }
std::string to_string() const;
std::string to_string(Unit const&) const;

private:
boost::units::quantity<Unit > x_;
boost::units::quantity<Unit > y_;
boost::units::quantity<Unit > z_;
}; // class point

template<class Unit>
boost::units::quantity<Unit>
point<Unit>::distance_from(point<Unit> const* point) const
{
return boost::units::sqrt(
boost::units::pow<2>(point->get_x() - this->x_) +
boost::units::pow<2>(point->get_y() - this->y_) +
boost::units::pow<2>(point->get_z() - this->z_));
} // distance_from

template<class Unit>
std::string
point<Unit>::to_string() const
{
std::ostringstream s;
s << '(' << this->x_ << ", "
<< this->y_ << ", " << this->z_ << ')';

return s.str();
} // to_string

template<class Unit>
std::string
point<Unit>::to_string(Unit const & unit) const
{
std::ostringstream s;
s << '(' << static_cast<BOOST_TYPEOF(unit)>(this->x_) << ", "
<< static_cast<BOOST_TYPEOF(unit)>(this->y_) << ", "
<< static_cast<BOOST_TYPEOF(unit)>(this->z_) << ')';

return s.str();
} // to_string

} // namespace cartesian_coordinate_system
} // namespace physics

#endif // PHYSICS_CARTESIAN_COORDINATE_SYSTEM_POINT_HPP
The units stuff is already tested and I know that is working well, but I think this perhaps has something to do with trying to use templates in this class, since I've not used them for a long time.

I have them all in a .hpp file because I heard that you have to have the class method definitions in the header file with the class declaration when you are using templates. is this true?

Anyway I have no idea why this isn't working, and haven't the slightest idea where to start to try to find the answer.

Thanks in advance for any help with this.