SitePoint Sponsor

User Tag List

Results 1 to 2 of 2

Hybrid View

  1. #1
    SitePoint Wizard bronze trophy devbanana's Avatar
    Join Date
    Apr 2006
    Location
    Pennsylvania
    Posts
    1,736
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    C++: Linking Error

    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.
    Laudetur Iesus Christus!
    Christ's Little Flock
    Jesus is the Good Shepherd

  2. #2
    SitePoint Wizard bronze trophy devbanana's Avatar
    Join Date
    Apr 2006
    Location
    Pennsylvania
    Posts
    1,736
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nevermind. I apparently forgot to define a constructor for physics::cartesian_coordinate_system:oint, among other errors.

    I have another question though. Say you have a method within a templated class. Is it possible to add another template type for that method itself? Something like:

    Code:
    template<class T1, class T2>
    foo<T1>::bar(T2 baz)
    {
    }
    How would such be declared within the class, and how would it be defined? Also if it is defined in a base class where the method is virtual, where does the virtual keyword go? Assuming this is possible, of course.

    The class point is templated for a certain unit type, but I want to be able to convert it to another.
    Laudetur Iesus Christus!
    Christ's Little Flock
    Jesus is the Good Shepherd


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •