Both Java generics and C++ templates have their advantages and disadvantages. Java generics produce less code and help minimize the size of executables whereas C++ rewrites entire template code for every different instantiations of a template. On the other hand, C++ templates support basic data types and even constant types as parameter argument whereas Java only supports classes as parameters for generics.
Why can't C++ have both? When user wanted to use the type inside a function, he could have used C++ style templates and otherwise he could have used Java style generics when declaring a parametric class/function. What technicality is preventing the implementation of this idea?
EDIT: For example consider this:
struct A {
virtual void do_something() {}
};
struct B: public A {
virtual void do_something() {}
};
template <typename T>
void call_do_something(T arg) {
arg.do_something();
}
int main() {
A a;
call_do_something(a);
B b;
call_do_something(b);
}
class A {
public void do_something() {}
}
class B extends A {
public void do_something() {}
}
class Z {
public static void <T extends A> call_do_something(T arg) {
arg.do_something();
}
}
public class Main {
public static void main(String[] args) {
Z.call_do_something(new A());
Z.call_do_something(new B());
}
}
As to my knowledge, when compiled, the above C++ code would generate two versions of call_do_something, one for A and one for B. But an equivalent code below in java would produce only one call_do_something. This would reduce generated executable size.
I'm not saying that Java generics are better than C++ templates. I was just curious to know why this is not implemented in C++, is there a technical reason for that, was it proposed in the past etc. Sorry for the confusion.
EDIT: This question was asked when I didn't know in depth about these concepts. Now that I think I have a better understanding of templates in C++ and generics in Java, I am trying to answer this question myself.
Java generics can benefit by using type erasure because it has single rooted class hierarchy and objects are always passed by reference (note that types that are passed by value like int and float can't be used in generics). Java compiler erases the actual generic type of the type parameter and replaces it with the upper bound of the parameter. Java's generics is more related to runtime polymorphism in C++.
On the other hand, C++ templates can do much more than Java generics. It can do call by value, it can instantiate a template with two unrelated classes etc. But it can't implement type erasure because objects can be passed by value and when done, their sizes and substructures vary and a single machine code cannot handle them all.
But in a particular scenario, if you have a common base class, and you are passing objects by reference, then you should not be going for templates in C++. You should use runtime polymorphism with virtual functions instead.
The below generified code in Java is actually equivalent to:
class AList<E extends A> {
private List<E> list = new ArrayList<E>();
public E add(E ele) {
list.add(ele);
return ele;
}
}
public class Main {
public static void main(String[] args) {
AList<B> l = new AList();
B b = l.add(new B());
}
}
this in Java:
class AList {
private List<A> list = new ArrayList<A>();
public void add(A ele) {
list.add(ele);
}
}
public class Main {
public static void main(String[] args) {
AList l = new AList();
B b = (B)l.add(new B());
}
}
and this in C++:
class AList {
private:
std::vector<A&> vec = {};
public:
A& add(A& ele) {
vec.push_back(ele);
return ele;
}
}
int main() {
AList l;
B btemp;
B& b = static_cast<B&>(l.add(&btemp));
}
TL;DR Type erasure is effective in Java generics since it has single rooted class hierarchy and objects are always passed by reference. Since these are not the case in C++, type erasure is not something that suits for C++ templates.
I thought of putting this in answers. But since the question is closed, and I failed in my try to reopen, I am adding it here.