Author Topic: Template problem  (Read 9526 times)

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Template problem
« on: August 21, 2010, 07:36:11 PM »
Feeling stupid again. What's wrong with this picture:

Code: [Select]
template<typename T>
void load_object_list(list<T> &v, K_File *sf)
{
Tar_Ball tb;
tb.Load(sf);
int s=tb.Get_Next_Value();
for (int t=0; t<s; t++)
{
T *o=new T;
o->Load(sf);
v.push_back(o);
}
}

I'm passing T as:
std::list<U_Door*> v_doors;

load_object_list(v_doors, sf);

That T *o=new T is failing. Damn templates! I hate 'em.

JayPC

  • Newcomer
  • Posts: 21
  • Karma: +0/-0
    • View Profile
    • Email
Re: Template problem
« Reply #1 on: August 22, 2010, 03:31:00 AM »
Dont even know what language this is but Have you tested to make sure its entering the for loop at all? also if list<U_door*> is a Cast and list<T> is a cast you have made me verry confused. as why your passing load_object_list() a U_door* List when it needs a T list...

Otherwise I cant help since Im guessing how any of this works haha!

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Template problem
« Reply #2 on: August 22, 2010, 05:04:04 AM »
You pass list<U_Door*> as argument.
So your T is 'U_Door*'.
T* is U_Door**.
U_Door** o=new (U_Door*);
is syntactically wrong.

Look at this:
Code: [Select]
template <class T>
struct GetType{
  typedef T Type;
};

template <class T>
struct GetType<T*>{
  typedef T Type;
};


template <class T>
class A{
};

template <class T>
void test(A<T>& a)
{
  typename GetType<T>::Type* t=new typename GetType<T>::Type;
}

int main()
{
  A<int*> a;
  A<int> b;
  test(a);
  test(b);
}
« Last Edit: August 22, 2010, 05:11:51 AM by Xecutor »

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Template problem
« Reply #3 on: August 22, 2010, 06:41:44 AM »
That example confused me more. I just want to create a new object type T. How to do that in this case?

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Template problem
« Reply #4 on: August 22, 2010, 07:25:17 AM »
In example there are template structure and specialization of the same template structure for pointers.
It's the way to convert T* to T.
Basically GetType<int*>::Type is int.
And GetType<int>::Type is int too.
But you need to add keyword typename before GetType<int>::Type.

Add GetType structures to your code, and change this line:
T *o=new T;
to this:
typename GetType<T>::Type* o=new typename GetType<T>::Type;

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Template problem
« Reply #5 on: August 22, 2010, 09:34:10 AM »
That was it. I have no idea why such complicated stuff is needed, but if it actually works then I care not.

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Template problem
« Reply #6 on: August 23, 2010, 06:41:54 AM »
It was a lil too late. So I solved different problem :)

Try it this way:
Code: [Select]
template<typename T>
void load_object_list(list<T*> &v, K_File *sf)
{
Tar_Ball tb;
tb.Load(sf);
int s=tb.Get_Next_Value();
for (int t=0; t<s; t++)
{
T *o=new T;
o->Load(sf);
v.push_back(o);
}
}

It's ALWAYS list of pointers. You can't pass list of values anyway.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Template problem
« Reply #7 on: August 23, 2010, 07:07:29 AM »
I was about to ask what is the difference with T and T* because I had a routine where I used T* and then changed it to T. Both compile fine, but which one is "correct"?

Code: [Select]
template<typename T>
void Refresh_Object_Map(list<T> &v)
{
for (typename list<T>::iterator pos=v.begin(); pos!=v.end(); pos++) (*pos)->Put_To_Map();
}

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Template problem
« Reply #8 on: August 23, 2010, 08:24:25 AM »
In this case it doesn't really matter.
If you make list<T*> and try to pass list<SomeClass>, compilation
error will be on call site, and in case of list<T> compilation error
will be during template instantiation, and as a result a little harder to track.

Btw this way:
Code: [Select]
template<typename T>
void Refresh_Object_Map(list<T> &v)
{
for (typename list<T>::iterator pos=v.begin(),end=v.end(); pos!=end; ++pos) (*pos)->Put_To_Map();
}
is a little bit more effective.
If you do not modify list in a cycle (which is bad idea anyway).