• Advertisement
Sign in to follow this  

c++ template causes linker error

This topic is 3955 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi After a day of searching for the error, I got truly desperate. Here's the code: vector.h:

#ifndef __vector_h__
#define __vector_h__

#define temp template <typename value>
#define vector3t vector3v<value>

	template <typename value>
	class vector3v
	{
	public:
		value x, y, z;
		
		vector3v();
		vector3v(const vector3t& vector);
        vector3v(value v1, value v2, value v3);

        void normalize();

        value& operator[] (size_t i);

        vector3t operator+ (const vector3t& vector) const;
        vector3t operator- (const vector3t& vector) const;
        vector3t operator* (const value& v) const;
        vector3t operator/ (const value& v) const;

        vector3t& operator+= (const vector3t& vector);
        vector3t& operator-= (const vector3t& vector);
        vector3t& operator*= (value& v);
        vector3t& operator/= (value& v);

        bool     operator== (vector3t& vector) const;
		bool	 operator!= (vector3t& vector) const;

		static vector3t crossProduct(const vector3t& a, const vector3t& b);
		static value dotProduct (const vector3t& a, const vector3t& b);
	};

	typedef vector3v<float>		vector3f;
	typedef vector3v<double>	vector3d;


#undef vector3t
#undef temp

#endif
and here's the implementation:
#include "vector.h"

#define temp template <typename value>
#define vector3t vector3v<value>


	temp vector3t::vector3v()
	{
	};


	temp vector3t::vector3v(const vector3t& vector) :
	x(vector.x),
	y(vector.y),
	z(vector.z)
	{
	};

	
	temp vector3t::vector3v(value _x, value _y, value _z) : 
	x(_x), 
	y(_y),
	z(_z)
	{
	};

    temp inline void vector3t::normalize()
	{
		value lenght = sqrt(x*x + y*y + z*z);
		x/=lenght;
		y/=lenght;
		z/=lenght;
	};

	temp inline value& vector3t::operator[] (size_t i)
	{
		return *(&x + i)
	};

	temp inline vector3t vector3t::operator+ (const vector3t& vector) const
	{
		return vector3t(x + vector.x,
						y + vector.y,
						z + vector.z);
	};
(...)

Everything compiles, but, whenever I try to even create an object of vector3f type (vector3v<float>) I get linker error: constructor not found (declared but not implemented). If I declare (in vector.h) a global const :
const vector3f _whatever;
the linker surprisingly finds the constructor, and it's starting to work. But then, for example, if I try to use anywhere the "+" operator... it cannot find it as well. Object Browser finds the declarations and the definitions, and yes, the file is being compiled, and it is a part of the project. I'm writing in Visual C++ 2005 Express, with SP 1. (without it was just the same). Any idea what's wrong?

Share this post


Link to post
Share on other sites
Advertisement
You need to put the implementation in the header, too, if it's a template.

But if you like the physical separation, you can #include an implementation file in to the header at the end (and omit the compilation of that file from the build).

There are only a handful of compilers available (one to my knowledge) that support "template export", the feature needed to separate template definitions from their declarations. And even then it's often a good idea to avoid the feature.

I'd really avoid the macro trickery too. For someone that's used to reading template code, it makes it much harder to read, IMO.

Edd

Share this post


Link to post
Share on other sites
ok, thanks, that explains a lot.

another question:

will it be possible to cast dynamically from vector3v<float> to vector3v<double> (and vice versa) if it is possible to cast from float to double?

Share this post


Link to post
Share on other sites
Quote:
will it be possible to cast dynamically from vector3v<float> to vector3v<double> (and vice versa) if it is possible to cast from float to double?


Sure the contents and container can be swapped with a cast, although float to double and vice versa casting does not require a dynamic cast as static is sufficient.


tempalte<typename TO, typename FROM>
vector3v<TO> vector3_cast(vector3v<FROM> const & rhs)
{
return vector3v<TO>( static_cast<TO>(rhs.x),static_cast<TO>(rhs.y),static_cast<TO>(rhs.z) );
}

vector3v<float> f;
vector3v<double> d( vector3v_cast<double>(f) );
f = vector3v_cast<float>(d);



You could also provide a constructor which is a conversion operator.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement