Mixing Templates and Generics

I think I've raised this questions a couple of times and the first time some three years ago - and have never got a real answer.

Why does the language disallow mixing templates and generics. What's wrong with:



template < typename T >
value struct outer {
  generic < typename U > void foo();
};

 


or



generic < typename T >
ref struct outer {
  template < typename U > void foo();
};

 


And in case you wonder, yes I really wrote some code which exactly does that and I don't think it's hard to think of examples.

-hg



Answer this question

Mixing Templates and Generics

  • Cached

    I believe the difference is that with Java generics, the generics are just there to give you compile time safety and to make the code not ugly.  It's still implemented underneath by passing Objects and casting back and forth, but with c++ templates, different code is generated for each thing you pass in between the <>. 

    (for instance ArrayList<MyClass> list; is the same as ArrayList list; except the compiler makes sure that the only thing you're putting into list is instances of MyClass and allow you to use MyClass mc = list.get(); without a cast back to MyClass.  With c++ templates, actual code is generated for each different argument you pass in between the brackets, so you in fact get a whole bunch of  different versions of the same function with different types).



  • George Ellis

    There is no reason beyond granting priority to the implementation of higher impact language features in a tight product cycle with limited resources, that some kind of template-generic combination was not implemented. The language design team is planning to look into possibilities for this feature as well as others in the near future.

    Stay tuned.



  • Desi29

    What would the IL representation of code sample #1 be   How would you implement method foo   If you reflected on the assembly containing outer and foo, what would you see (I'm thinking specifically of how many outers and foos there would be.)

    The same questions apply to sample #2.

    As to your question, my (uninformed) guess would be that tossing this extra complexity into the language just wasn't worth the risk of producing an compiler that produced incorrect code.

  • DavP

     Jeff Peil wrote:

    There was a clear and important decision in the standardization process. Don't standardize things we don't yet have enough experience with.  That isn't to say this isn't a future direction, merely that without prior implementation experience it would have been unwise to try to describe exactly how all of the rules around these two features could/should combine (for instance could you have a template-generic function, something like "template<class T> generic<class U> where U: T void Foo(T t, U, u)" and if you can exactly what are all of the deduction rules, etc.)  While alot of this may seem straight forward, in my experience, if you haven't taken all of the time necessary to work through the implementation issues, there are going to be a lot of things you overlook in the process.  Due to the fact that there was no implementation experience here, and given complexity of templates and generics I think this was a reasonable choice for the standard.

    Thanks for the explanations. That makes perfect sense. However, all that being said, it is hard to tell why a particular clause was included (at least for me).

    -hg

  • RockoRobotics

    Hi,
            I come from the Java world where they use generics. Not templates. There are differences. Could you explain what you meant by 'tempates' and 'generics'

    Thanks,
    Mohan

  • greyhound75635

    On a related note, what's the appropriate way to report issues or request changes in the standard. For instance, the whole point of the last paragraphs in §31.3.2 is strange. Specifically, why should the last statement in the last example fail

    Of course, VC still doesn't get the corresponding standard C++ case, right. *sigh*

    -hg

  • .net_Coder

    So does it mean the C++/CLI standard (1.15) is wrong/outdated in a couple of places, e.g.:

    §31.1.10:
    A generic type cannot be nested in a class-template.
    [...]
    A program
    having a generic type nested within a class template is ill-formed.



    On a second look, I can't seem to find similar provisions for generic functions or class/function templates nested into generic types.


  • bchase

     Holger Grund wrote:

    That's interesting. I thought VC++ and the standard were independent. VC++ simply not fully implementing it (such as the CLR not being a complete implementation of the CLI standard). And in fact, that would make a more sense IMHO. After all there are already things like "Mixed Types" in the docs.


    There was a clear and important decision in the standardization process. Don't standardize things we don't yet have enough experience with.  That isn't to say this isn't a future direction, merely that without prior implementation experience it would have been unwise to try to describe exactly how all of the rules around these two features could/should combine (for instance could you have a template-generic function, something like "template<class T> generic<class U> where U: T void Foo(T t, U, u)" and if you can exactly what are all of the deduction rules, etc.)  While alot of this may seem straight forward, in my experience, if you haven't taken all of the time necessary to work through the implementation issues, there are going to be a lot of things you overlook in the process.  Due to the fact that there was no implementation experience here, and given complexity of templates and generics I think this was a reasonable choice for the standard.


     Holger Grund wrote:
    I'm running into all kinds of problems when trying to create some generic library code with C++/CLI. In that case I was looking at some metaprogramming trickery to implement specialization for generics.

    Anyway, I fail to see why one would _not_ want to mix these concepts. AFAICT, it is effectively impossible to use templates to construct anything that is or conists of something generic.


    Agreed, based on the types of combinations you can already make today that are incredibly powerful (like template classes implementing generic interfaces) it seems clear that there is alot of value in allowing these to contructs to more fully mix.  It's unfortunate that this wasn't something we had time to get done in VS 2005.


  • Naturalis

    The translation should be fairly trivial. Templates are instantiated as usual. I.e. in the first example, if - and only if - a given outer<T> is instantiated, it will be emitted as a CLR TypeDef. It will have a generic MethodDef for foo (if that is instantiated or always)

    It's exactly the same in C++/CLI if foo is just an ordinary (i.e. non-generic) method. You get a distinct CLR TypeDef for each instantiation of outer. From CLR perspective these are simply different types.

    In the second example, you'd get a single TypeDef for outer and one MethodDef for each instantiated method.

    These are just the standard rules for template instantiations. Disallowing these constructs (especially the one in the first example) looks like an arbitrary limitation.

    -hg

  • Andy Cutler

    This is going to sound a bit like splitting hairs, so let me apologize in advance. :)

    I would say that the standard is correct. With this version of the standard, that construction is indeed ill-formed.

    When and if template-generics are implemented, a new version of the standard will be released.

    Visual C++ 2005 implements Version 1.0 of the standard.

    The fact that the other direction is not explicitly mentioned as ill-formed seems an oversight, though you have to admit that standards rarely explicity mention all variants of ill-formed code.

    In what context do you find the combination of templates and generics compelling What paradigm were you trying to implement

  • Paul Crowder

     Dean Wills MSFT wrote:
    This is going to sound a bit like splitting hairs, so let me apologize in advance. :)

    Um, I think the powers that be (or at least Ronald) should know my opinion on stuff like that by now :-O

     Dean Wills MSFT wrote:
    I would say that the standard is correct. With this version of the standard, that construction is indeed ill-formed.

    When and if template-generics are implemented, a new version of the standard will be released.

    Visual C++ 2005 implements Version 1.0 of the standard.


    That's interesting. I thought VC++ and the standard were independent. VC++ simply not fully implementing it (such as the CLR not being a complete implementation of the CLI standard). And in fact, that would make a more sense IMHO. After all there are already things like "Mixed Types" in the docs.

    Apart from that, someone (IIRC Jeff Peil) said back in 2002 it wouldn't be supported ...

     Dean Wills MSFT wrote:

    In what context do you find the combination of templates and generics compelling What paradigm were you trying to implement

    I'm running into all kinds of problems when trying to create some generic library code with C++/CLI. In that case I was looking at some metaprogramming trickery to implement specialization for generics.

    Anyway, I fail to see why one would _not_ want to mix these concepts. AFAICT, it is effectively impossible to use templates to construct anything that is or conists of something generic.

    -hg


  • Mixing Templates and Generics