SitePoint Sponsor

User Tag List

Results 1 to 2 of 2
  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.

  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.


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
  •