7

I have an interface IEnumerable for template classes of List<>, Array<> and Dictionary<>. I was hoping to use typedef to get their templated types T.

I was hoping to do the following.

class IEnumerable
{
public:
    virtual typedef int TemplateType;
}

And then override in inherited member, but you cant make a virtual typedef. So is there any other way that i could get the type of an unknown template class (IEnumerable is not template)?

Sellorio
  • 1,806
  • 1
  • 16
  • 32
  • Retagged as C#, since to the best of my knowledge `virtual typedef` isn't a C++ feature. – templatetypedef Feb 07 '13 at 00:20
  • 1
    @templatetypedef did u read the question?! i said that virtual typedef doesn't work and asked for opinions on alternatives. untag plz! – Sellorio Feb 07 '13 at 00:24
  • My apologies - since you were using type names like `IEnumerable`, `List`, `Array`, and `Dictionary`, I assumed this was C# code (since these types aren't built into C++). Sorry about that! – templatetypedef Feb 07 '13 at 00:25
  • @templatetypedef no probs. i can see how my names would confuse. Do you have any ideas as to the problem? – Sellorio Feb 07 '13 at 00:26
  • Is there a reason you're not defining IEnumerable as a template class as well? – thang Feb 07 '13 at 00:27
  • @thang i want to have it the same for all (like in c#, im a copy cat :P) and i also need it like this to allow me to make Reflection-like functionality. – Sellorio Feb 07 '13 at 00:28
  • @MrUniverse So is it a template or not? I'm sure you can do what you're asking, but we need to see where `template` goes and what the template parameter is. – Potatoswatter Feb 07 '13 at 00:30
  • 2
    No, you can't do that. Types will be resolved at compile time, so dynamic typing has no place in it. – K-ballo Feb 07 '13 at 00:30
  • So C# can do this not because they can do virtual typedef. They use a base class of Object. You can do the same. Define a class of type Object. Derive all of your collection element types from Object. Then set up exactly the same pattern that C# does... – thang Feb 07 '13 at 00:41
  • @thang yeah i was thinking of doing an Object class. but is List< T> where T : Object == List< Object>? would the compiler be able to convert the 2 implicitly? – Sellorio Feb 07 '13 at 00:54
  • @thang also how would i resolve the Object into a derived type without doing a dynamic cast of any possible type and then decltype that? is there a more reusable way of doing this? – Sellorio Feb 07 '13 at 00:55
  • actually you know, in c++11, you can just make the enumerator a template. when you need to use it, i think you can use the auto keyword (http://stackoverflow.com/questions/8542873/c11-auto-semantics). so when you access the enumerator, instead of having to do IEnumarator u = collection.getEnumerator(); you can just do auto u = collection.getEnumerator(); I think that should work. – thang Feb 07 '13 at 00:58
  • @thang auto (c++) == var (in c#)? – Sellorio Feb 07 '13 at 01:05
  • 1
    yeah implicit type. that's right. – thang Feb 07 '13 at 01:08

1 Answers1

6

Well, here is what is discussed in the comments in case somebody with the same question later finds this.

Basically, you want to do something similar to C#'s List<>, Array<>, IEnumerable and IEnumerator. However, you don't want to have to create a generic parent class Object because it may mean that you'll need to dynamic_cast every time.

Additionally, you don't want to make IEnumerable a template because you don't want to have to know the type when using the collection.

In fact, with C++11, you can make IEnumerable a template and not have to know the type by using the implicit type keyword auto, which is the C++11 equivalent of c#'s var keyword.

So to do this, what you can do is:

 template <class T>
 class IEnumerable { 
     public:
        virtual IEnumerator<T> getEnumerator() = 0; 
        // and more stuff
 }

then

  template <class T>
  class List : public IEnumerable<T> { 

  public:
         virtual IEnumerator<T> getEnumerator() { 
               return ListEnumerator<T>(this); 
         }
  }

and

  template <class T>
  class ListEnumerator : public IEnumerator<T> { 
  public:
        T getNext();   // or something to this effect
        // and more stuff
  }

Finally, when it comes to using it, you can do:

  List<int> myList;


  auto i = myList.getEnumerator();
  int z = i.getNext()+1;
thang
  • 3,466
  • 1
  • 19
  • 31
  • +1 a very good summing up. now even i understand it all better :P – Sellorio Feb 07 '13 at 03:26
  • also can i do ListEnumerator = myList.getEnumerator(); ? – Sellorio Feb 07 '13 at 03:27
  • and can i typedef auto (aka typedef ListEnumerator ListEnum;) – Sellorio Feb 07 '13 at 03:30
  • your joking?! List works! naaaa i dont believe it. its too awesome even for c++ :P ill check it out tomorrow – Sellorio Feb 07 '13 at 10:22
  • actually, I don't know. I thought you tried it! turns out it doesn't work; however, boost::any works the same way. http://stackoverflow.com/questions/12176972/using-auto-as-a-template-parameter – thang Feb 07 '13 at 10:33
  • you know, it seems strange to me that you can't do something with auto in the template argument. seems like you should be able to resolve it at compile time... – thang Feb 07 '13 at 10:43
  • yeah but as implied, i didnt expect it to be that smart anyway :( ah well. thanks for your time and comments, i learnt a lot :) – Sellorio Feb 07 '13 at 21:48