Convert templated class.

Started by
2 comments, last by CTar 18 years, 11 months ago
Well, I have a class(Timer class) which takes a template paramater, which determines what kind of type the elapsed/absolute time is. My problem is that i can't convert between to types, for example Timer<float> and Timer<double>. So how can I do this? I have tried doing something like this:

//Typed it in on GDNet, so might have a syntax error or two.
template<class T2>
operator Timer<T2>()
{
	Timer Temp;
	Temp.mElapsedMS = mElapsedMS;
	Temp.mInvMSFrequency = mInvMSFrequency;
	Temp.mLastTime = mLastTime;
	Temp.mUsingPerformanceCounter = mUsingPerformanceCounter;
	return Temp;
}

The problem with this approach is that I can't access Temp's protected members. So I tried something with friends(the C++ ones), but I couldn't get it to work. Does anyone have a way to do this? I don't want to make my members public or make getters and setter for all members. The full source of my Timer class is here:


//Class: Timer
//Used to get absolute and/or relative(from last update)
//time.
template < typename T = double >
class Timer
{
public:
	Timer()
	{
		//Retrieve the frequency, if performance counters are supported. Also
		//set mUsingPerformanceCounter to true if performance counters are supported,
		//if not set to false.
		INT64 Frequency = 0;
		mUsingPerformanceCounter = QueryPerformanceFrequency( (LARGE_INTEGER*)&Frequency );

		//If performance counters are supported calculate the inverted frequency for
		//milliseconds and get the current time.
		if(mUsingPerformanceCounter)
		{
			mInvMSFrequency = static_cast<T>(1000.0)/static_cast<T>(Frequency);
			QueryPerformanceCounter( (LARGE_INTEGER*)&mLastTime );
		}
		//If performance counters aren't supported get last time.
		else
		{
			mLastTime = timeGetTime();
		}
	}
	~Timer()
	{
		//Reset all members.
		//
		//Please note that mUsingPerformanceCounter
		//is set to TRUE and mInvFrequency is set to
		//0, this means that the return of:
		//GetElapsed*() and GetAbsolute*() always will be
		//0.
		mUsingPerformanceCounter = TRUE;
		mInvMSFrequency = 0;
		mLastTime = 0;
	}
		//Function: Update
	//Update the time. When retrieving the absolute time
	//it ain't the current time, but the absolute time at
	//the time of the update.
	//Relative is also the time between last update and the
	//update before.
	void Update()
	{
		if(mUsingPerformanceCounter)
		{
			//Insert the current time in CurrentTime.
			SINT64 CurrentTime = 0;
			QueryPerformanceCounter( (LARGE_INTEGER*)&CurrentTime );
				//Calculate the number of elapsed milliseconds since last update.
			mElapsedMS = static_cast<T>(CurrentTime - mLastTime)*mInvMSFrequency;
			//Set the mLastTime variable to the current time
			//because this is now the last time.
			mLastTime = CurrentTime;
		}
		//If QueryPerformance* aren't available.
		else
		{
	
			//Retrieve current time.
			DWORD CurrentTime = timeGetTime();
			//Calculate the number of elapsed milliseconds.
			mElapsedMS = static_cast<T>(CurrentTime-mLastTime);

			//Set the mLastTime variable to the current time
			//because this is now the last time.
			mLastTime = CurrentTime;
		}
	}

	//Function: GetElapsedMS
	//Retrieve the time between the last update
	//and the update before that in milliseconds.
	T GetElapsedMS() const
	{
		//Just return the member, was calculated in the Update function.
		return mElapsedMS;
	}

	//Function: GetElapsedSecs
	//Retrieve the time between the last update
	//and the update before that in seconds.
	T GetElapsedSecs() const
	{
		//Just return the number of milliseconds divided by 1000(multiply by
		//0.001 equals divide by 1000).
		return mElapsedMS*0.001;
	}
	//Function: GetAbsoluteTimeMS
	//Retrieve the absolute time in milliseconds.
	T GetAbsoluteTimeMS() const
	{
		return static_cast<T>(mLastTime)*mInvMSFrequency;
	}

protected:

	//Variable: mUsingPerformanceCounter
	//Marks if a performance counter(QueryPerformance*) is
	//used.
	BOOL mUsingPerformanceCounter;
	//Variable: mInvMSFrequency
	//The inverted frequency(1.0/Frequency), only used with performance counters.
	T mInvMSFrequency;

	//Variable: mElapsedMS
	//The number of elapsed milliseconds between last update
	//and the update before.
	T mElapsedMS;

	//Variable: mLastTime
	//The absolute time of last update.
	//
	//Remarks:
	//- Multiply by mInvMSFrequency to convert to milliseconds.
	//- SINT64 = signed 64 bit integer.
	SINT64 mLastTime;
};

Advertisement
template<class T>class Timer{public:      Timer(T time) : time_(time) {}   template<class U> friend class Timer;   template<class U> operator Timer<U>() { return Timer<U>(time_); }private:   T time_;};
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
One way would be to derive the Timer<> classes from a TimerBase class which has a protected Set() method using some base type, i.e doubles. Include this in the Timer<> classes to set all the member variables up and then you rewrite your operator Timer<T2>() function to use Temp.Set(mElapsedMS, mInvMSFrequency ...)
Thanks for the answer, got it to work(with the "template<typename U> friend class Timer;").

This topic is closed to new replies.

Advertisement