About generics in Kotlin vs C++


#1

Hello
I tried this and I am very surprise to not be able to compile this code…

image

Can someone explain the topic ? and what code can I write to be able to add my Complex ?


#2

Maybe you could describe what you are trying to do. Why should this compile? What do you expect g.reel + d.reel to do?

Here’s some things that I notice that could help:

  • You’ve defined two different T generic types with the same name (one for Complexe and one for the plus function)
  • The plus function is not an operator plus function (it will not work when using +)
  • Your T types don’t have any restrictions so both T generic types are really T: Any?, is that what you want?

#3

C++ Templates work very different to how jvm generics work. When you have a template class or function in C++ the compiler will generate multiple classes/functions for each different call. So if we take your code from above in C++ and call it once with an int and once with a float the compiler will create 2 classes for Complex and 2 functions for plus one with int and float each.
As far as I’m aware you can specify constraints on the type, but you don’t have to, because the compilation fails anyways if you try to use a type, which won’t work.

Generics on the JVM (which Kotlin is running on) work very differently. Every type parameter has an upper bound (the default is java.lang.Object in java and Any? in Kotlin). Your above code compiles to something that looks a bit like this

class Complexe(val reel: Any?, val img: Any?)
fun plus (g: Complexe, d: Complexe) : Complexe {
    return Complexe(g.reel + d.reel, g.img + d.img)
}

This is not exactly what happens but it should explain how it works. This is what people mean when they talk about the type erasure in java/kotlin. Generic type information get’s lost during compilation.
For those reason generics are more limited than c++ templates. This has both disadvantages and advantages.

PS: If you mean “Complex” as in “complex numbers”, you have a few spelling mistakes. reel -> real and Complexe should be Complex


#4

Your + operator is not defined for arbitrary type T. It is exactly the same in C++. Though, templates are not the same as generics.


#5

It is in french, I think. It is general convention to use English names everywhere, but is not the rule.


#6

I agree and I definitely didn’t mean to judge, but since this is an english forum it makes it easier to understand. Even though the code sample is short and quite easy to understand I had to look at it for a while to realize what he was trying to do and from what @arocnies wrote I think he had the same problem.


#7

Indeed, I was confused as well.


#8

Yes Complexe IS a french word. Not the problem I guess.
I see the template is notre able to compile because + operator doesn’t exist on Any. But firstly it doesn’t compile even if T is contraint to be Number.
The next question is : how to propose a “plus” function to add two Complex ?


#9

Thanks. Very clear explanation.


#10

Number does not define +. Use Double and it will work.

In order to overload operator you have to define operator fun plus(other: X): X directly or via extension. See documentation on operation overloading.


#11

Anyone who has a bit experience with compiling generics in C++ would remember how horrible it is to debug through all the backlog of how template expansion propagated wrong types when you passed something wrong. In Java or Kotlin, they check the correctness of the type parameters as soon as possible to prevent having to dig through the enormous template expansion backtrace.