Using array of templated class inside templated class?

Started by
8 comments, last by SiCrane 12 years, 6 months ago
i have something like this





template <int blah>
class myclass
{
templated inline functions and stuff here;
want to use ARRAY somewhere here;
};


template <1> class myclass ARRAY[9001];




What do i need to do to be able to use ARRAY inside myclass?
I want to fill ARRAY using a function not belonging to the class.
I was thinking of somehow making it a static member of myclass, but im sure that wouldnt work with templates. The array is a lookup table btw.
That above code is in a header file and the function definition for the array filler will be in a cpp.

Is this even possible? I think i heard theres no way to declear templated classes. I could just make it a table of primitive types and convert them, but i dont like it...

o3o

Advertisement
This can be done either as a global variable or a static member variable.

// as a global
template <int i> struct Foo {
void foo(void);
};

Foo<1> foo_array[9001];

template <int i> void Foo<i>::foo(void) {
Foo<1> temp = foo_array[0];
}

// as a static
template <int i> struct Bar {
static Bar<i> bar_array[9001];

void foo(void) {
Bar<i> temp = bar_array[0];
}
};

template <int i> Bar<i> Bar<i>::bar_array[9001];

This can be done either as a global variable or a static member variable.

// as a global
template <int i> struct Foo {
void foo(void);
};

Foo<1> foo_array[9001];

template <int i> void Foo<i>::foo(void) {
Foo<1> temp = foo_array[0];
}

// as a static
template <int i> struct Bar {
static Bar<i> bar_array[9001];

void foo(void) {
Bar<i> temp = bar_array[0];
}
};

template <int i> Bar<i> Bar<i>::bar_array[9001];




Oh wait, i didnt realize i can just put the functions outside the class... >.<
I propably thought it wouldnt be possible as i read you cant put them to different files or something like that :P

Wouldnt the static version create a new array for each template?

o3o

The static version has a separate array per template instantiation.
Cant get it work...

I get error "unable to match function definition to an existing declaration" :c


My code is like:


template<blah>
class A
{
A<blah> func();
};


template<blah>
A<blah> A<blah>::func()
{

}





Is there something wrong in doing it like that?

o3o

Post the actual code giving you problems.
Ok, though i dont know what else could be causing the problem... note that this problem has nothing to do with the array problem, its not letting me to define the functions outside the class...
Its a fixed point class im making for some reason.

The 3 functions (named sin cos and tan) im having problems with come after a line of ////


#ifndef LEFIXEDPOINTMATH_H
#define LEFIXEDPOINTMATH_H

#include "leMathDefines.h"



#ifndef TRIG_LOOKUP_TABLE_SIZE
#define TRIG_LOOKUP_TABLE_SIZE 1024
#endif



template <typename Type,const i32 FractionSize>
class Num
{
private:
Type Value;
static const i32 FractionSize=FractionSize;
public:
//Return value shifted to fraction size of FracBits
inline Type GetShiftedValue(const i32 FracBits)
{
if (FractionSize == FracBits)
{
return Value;
}
else if (FractionSize < FracBits)
{
return Value << (FracBits - FractionSize);
}
else
{
return Value >> (FractionSize - FracBits);
}
}

//Set raw value, dont do any shifting
inline void SetRawValue(Type newValue)
{
Value=newValue;
}

//Assignment operator
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator=(Num<OType,OFractionSize> Other)
{
Value=Other.GetShiftedValue(FractionSize);
return *this;
}

//Assignment operator for doubles
inline Num<Type,FractionSize>& operator=(double Other)
{
Value=static_cast<Type>(Other*pow(2.0, FractionSize));
return *this;
}

//Assignment operator for floats
inline Num<Type,FractionSize>& operator=(float Other)
{
Value=static_cast<Type>(Other*pow(2.0f, FractionSize));
return *this;
}

//Assignment operator for i32s
inline Num<Type,FractionSize>& operator=(i32 Other)
{
Value=static_cast<Type>(Other << FractionSize);
return *this;
}

//Conversion to double
inline operator double()
{
return static_cast<double>(Value)/pow(2.0,FractionSize);
}

//Conversion to float
inline operator float()
{
return static_cast<float>(Value)/pow(2.0f,FractionSize);
}

//Conversion to i32
inline operator i32()
{
return static_cast<i32>(Value >> FractionSize);
}

//Conversion to short
inline operator short()
{
return static_cast<short>(Value >> FractionSize);
}

//Conversion to signed char
inline operator signed char()
{
return static_cast<signed char>(Value >> FractionSize);
}

//Addition assignment operator +=
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator+=(Num<OType,OFractionSize> Other)
{
Value += Other.GetShiftedValue(FractionSize);
return *this;
}

//Subtraction assignment operator -=
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator-=(Num<OType,OFractionSize> Other)
{
Value -= Other.GetShiftedValue(FractionSize);
return *this;
}

//Multiplication assignment operator *=
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator*=(Num<OType,OFractionSize> Other)
{
Value=static_cast<Type>((static_cast<ui64>(Value) * Other.GetShiftedValue(FractionSize)) >> FractionSize);
return *this;
}

//Division assignment operator /=
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator/=(Num<OType,OFractionSize> Other)
{
Value=static_cast<Type>((static_cast<ui64>(Value) << FractionSize) / Other.GetShiftedValue(FractionSize));
return *this;
}

//Modulus assignment operator %=
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize>& operator%=(Num<OType,OFractionSize> Other)
{
Value=(Value % Other.GetShiftedValue(FractionSize));
return *this;
}

//Addition operator +
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator+(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value);
Temp+=Other;
return Temp;
}

//Subtraction operator -
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator-(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value);
Temp-=Other;
return Temp;
}

//Multiplication operator *
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator*(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(static_cast<Type>((static_cast<ui64>(Value) * Other.GetShiftedValue(FractionSize)) >> FractionSize));
return Temp;
}

//Division operator /
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator/(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(static_cast<Type>((static_cast<ui64>(Value) << FractionSize) / Other.GetShiftedValue(FractionSize)));
return Temp;
}

//Modulus operator %
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator%(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value % Other.GetShiftedValue(FractionSize));
return Temp;
}

//right shift operator
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator>>(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value >> Other.GetShiftedValue(0));
return Temp;
}

//left shift operator
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator<<(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value << Other.GetShiftedValue(0));
return Temp;
}

//Power operator
template <typename OType,const i32 OFractionSize>
inline Num<Type,FractionSize> operator^(Num<OType,OFractionSize> Other)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(Value);
for (i32 i=1; i<Other.GetShiftedValue(0); ++i)
{
Temp *= Temp;
}
return Temp;
}

//Square root
inline Num<Type,FractionSize> sqrt(i32 iterations)
{
Num<Type,FractionSize> Temp;
Temp.SetRawValue(1);
for (i32 i=0; i<iterations; ++i)
{
Temp=(Temp + (Temp / (*this))) >> static_cast< Num<Type,FractionSize> >(2);
}
return Temp;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////HERE ISH DECLEARATIONS
//Sin
Num<Type,FractionSize> sin();

//Cos
Num<Type,FractionSize> cos();

//Tan
Num<Type,FractionSize> tan();

//Equal operator ==
template <typename OType,const i32 OFractionSize>
inline bool operator==(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value == Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value == Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) == Other.Value;
}
}

//Not equal operator !=
template <typename OType,const i32 OFractionSize>
inline bool operator!=(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value != Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value != Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) != Other.Value;
}
}

//Greater than operator >
template <typename OType,const i32 OFractionSize>
inline bool operator>(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value > Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value > Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) > Other.Value;
}
}

//Smaller than operator <
template <typename OType,const i32 OFractionSize>
inline bool operator<(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value < Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value < Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) < Other.Value;
}
}

//Greater or equal to operator >=
template <typename OType,const i32 OFractionSize>
inline bool operator>=(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value >= Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value >= Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) >= Other.Value;
}
}

//Smaller or equal to operator <=
template <typename OType,const i32 OFractionSize>
inline bool operator<=(Num<OType,OFractionSize> Other)
{
if (Other.FractionSize == FractionSize)
{
return Value <= Other.Value;
}
else if (Other.FractionSize > FractionSize)
{
return Value <= Other.GetShiftedValue(FractionSize);
}
else
{
return GetShiftedValue(Other.FractionSize) <= Other.Value;
}
}

//Constructor
Num(){}

//Constructor, set value as i32s
template<typename valueType>
Num(valueType value)
{
(*this)=value;
}

};



Num<i32,30> TrigLookupTable[TRIG_LOOKUP_TABLE_SIZE];

void BuildLookupTables();

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////GIVES ERROR ON THE NEXT 3 FUNCTION DEFINITIONS (havent written code in them yet)
//Sin
template <typename Type, const i32 FractionSize>
Num<Type,FractionSize> Num<Type,FractionSize>::sin()
{
Num<Type,FractionSize> lol=1;
return lol;
}

//Cos
template <typename Type, const i32 FractionSize>
Num<Type,FractionSize> Num<Type,FractionSize>::cos()
{

}

//Tan
template <typename Type, const i32 FractionSize>
Num<Type,FractionSize> Num<Type,FractionSize>::tan()
{

}


#endif

o3o

Try getting rid of this line:

static const i32 FractionSize=FractionSize;

Try getting rid of this line:

static const i32 FractionSize=FractionSize;



Thanks, works now!

It was different name than the template one but i guess i accidentally changed it while using the find and replace thing to change the name of something...

o3o

Incidentally, when posting code you're having trouble with, you should get in the habit of posting complete, but minimal, code samples. Your first code sample wasn't complete because it didn't demonstrate the problem you were complaining about. The second wasn't minimal because it contained a lot of code that didn't relate to the problem. If you had taken the time to create a complete and minimal code sample you may have been able to identify the problem on your own.

This topic is closed to new replies.

Advertisement