Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes a template different from a generic?

I understand the aspects of templates in C++ that are different from generics in Java and C#. C# is a reification, Java uses type erasure, C++ uses duck typing, etc. There are a number of things C++ templates can do that Java and C# generics can't (e.g. template specialization). But there are a number of things Java generics can do that C# and C++ can't (e.g. make a bounded type parameter of a family of generics like class Foo<T extends Comparable<?>>), and a number of things C# generics can do that Java and C++ can't (e.g. runtime generic reflection). [EDIT: Apparently Java generics are much weaker than I thought. (Which is saying something.) In any case, despite their ineptness, they are still considered generics along with C#'s generics.]

What I don't understand is what conceptually makes templates different from generics. What parts of C++ templates are things that cannot be done in something that isn't a template, but is a generic? For example, if I were to implement a language that supported templates, what would absolutely need to be in it? What could I leave out that would be necessary for the language to support generics?

My guess is that templates are a super-set of generics or they are a way to implement generics, but I don't really understand what separates a true template from a true generic.

like image 757
Eva Avatar asked Mar 26 '13 10:03

Eva


People also ask

What does generic template mean?

The generic template is a simple structured message that includes a title, subtitle, image, and up to three buttons. You may also specify a default_action object that sets a URL that will be opened in the Messenger webview when the template is tapped.

Are templates more powerful than generics?

In C++ when you use a template the compiler will emit the template code again after replacing the generic parameter in it with the type you used. This is more powerful in several ways but can lead to bloated executables.

What is a generic class class template?

Templates are the foundation of generic programming, which involves writing code in a way that is independent of any particular type. A template is a blueprint or formula for creating a generic class or a function.

What are generic pointers and templates?

Generics are syntax components of a programming language that can be reused for different types of objects. Typically, generics take the form classes or functions, which take type(s) as a parameter. Generics are also commonly referred to as templates , and in C++ are officially called templates.


2 Answers

Hm.. if you say you understand C++ templates in depth and say that you don't see/feel the difference between generics and them, well, that most probably you are right :)

There are many differences that will describe how/why generics are better than templates, list tons of differences, etc, but that's mostly irrelevant to the core of the idea.

The idea is to allow better code reuse. Templates/generics provide you a way to build a some kind of higher-order class definitions that abstract over some of the actual types.

In this terms, there is no difference between them, and the only differences are those enforced by specific features and constraints of the underlying language and runtime.

One may argue that generics provide some extra features (usually when talking about dynamic introspection of object's class tree), but very few of them (if any at all) cannot be implemented manually in C++'s templates. With some effort, most of them can be implemented, or emulated, hence they are not good as a distinction between 'proper generics' and 'real templates'.

Others will argue that the sheer potential power of optimization that is available thanks to the C++'s copy-paste behavior is the difference. Sorry, not true. JITs in Java and C# can do it too, well, almost, but do it very well.

There is however one thing that really could make the Java/C#'s generics a true subset of C++'s templates features. And you even have mentioned it!

It is template specialization.

In C++, each specialization behaves as a completely different definition.

In C++, template<typename T> Foo specialized to T==int may look like:

class Foo<int> 
{
    void hug_me();

    int hugs_count() const;
}

while "the same" template specialized to T==MyNumericType may look like

class Foo<MyNumericType> 
{
    void hug_me();

    MyNumericType get_value() const;
    void  reset_value() const;
}

FYI: that's just pseudocode, won't compile:)

Neither Java's nor C#'s generics can do that, because their definition states that all generic-type-materializations will have the same "user interface".

More to it, C++ uses a SFINAE rule. Many "theoretically colliding" specializations' definitions may exist for a template. However, when the template is being used, only those "actually good" are used.

With classes similar to the example above, if you use:

 Foo<double> foood;
 foood.reset_value();

only the second specialization would be used, as the first one would not compile because of ... "reset_value" missing.

With generics, you cannot do that. You'd need to create a generic class that has all possible methods, and then that would at runtime dynamically inspect the inner objects and throw some 'not implemented' or 'not supported' exceptions for unavailable methods. That's... just awful. Such things should be possible at compile-time.

The actual power, implications, problems and overall complexity of template specialization and SFINAE is what truly differentiates the generics and templates. Simply, generics are defined in a such way, that specialization is not possible, hence SFINAE is not possible, hence, the whole mechanism is paradoxically much easier/simplier.

Both easier/simplier to implement in the compiler's internals, and to be understood by non-savant brains.

Although I agree with the overall benefits of generics in Java/C#, I really miss the specializations, interface flexibility, and SFINAE rule. However, I would not be fair if I'd not mention one important thing related to sane OO design: if you template-specialization for type xxx actually changes it's client API, then most probably it should be named differently and should form a different template. All the extra goodies that templates can do were mostly added to the tools set because ... in C++ there was no reflection and it had to be emulated somehow. SFINAE is a form of compile-time reflection.

Hence, the biggest player in the world of differences gets reduced to a curious (beneficial) sideeffect of a hotfix applied to mask the runtime's deficiency, which is the almost complete lack of runtime introspection :))

Therefore, I say that there are no difference other than some arbitrary ones enforced by laguage, or some arbitrary ones enforced by the runtime platform.

All of them are just a form of higher-order classes or functions/methods, and I think that this is the most important thing and feature.

like image 98
quetzalcoatl Avatar answered Sep 20 '22 06:09

quetzalcoatl


First, I find it interesting that RTTI/introspection is a big part of most of the answers. Well, that is not a difference of generics vs. templates, but rather languages with instrospection vs. languages that don't have it. Otherwise you can also claim that to be a difference of C++ classes with Java classes, and C++ functions with Java functions...

If you take instrospection out of the way, the main difference is that templates define a turing complete language, functional in style although with a horrible grammar at it on which you can program. The first really complex example I heard of (I would love having the code, but I don't) was a program that calculated prime numbers at compile time. Which does bring another difference: templates can take type arguments, or template arguments or non-type arguments (non-type refers to anything that is not a type or a template, like an int value).

This has been mentioned in other answers, but just saying that templates can be specialized and that there is SFINAE does not clearly state that those two features are sufficient to generate a turing complete language.

like image 26
David Rodríguez - dribeas Avatar answered Sep 20 '22 06:09

David Rodríguez - dribeas