Dealing with overload resolution ambiguity


#1

Hi all,

I am having an issue resolving an overload resolution ambiguity problem calling some Java code. I can re-produce the problem in pure Kotlin for brevity. Consider the following class:

class DoubleIndex<T> {

    fun select(rowOrdinal: Int): Double  {
        return Double.NaN
    }

    fun select(rowKey: T?): Double {
        return Double.NaN;
    }
}

I now create an instance of this class with type T = Int. How can I force a call on the select() method that takes the primitive int value rather than the Int key value? You may argue that the API is badly designed, but I am facing this issue with a third party Java library. Is there anyway to force calling one method versus the other?

    val index = DoubleIndex<Int>();
    index.select(2)

The above code does not compile as it doesn’t know which method to call. We can force calling the second method as follows, but it is not clear how we can force call the first.

    val index = DoubleIndex<Int>();
    index.select(2 as Int?)

Thanks!
Zav


#2

The only way I could find to force the first overload to be called is like this:

val index = DoubleIndex<Long>() 
index.select(2.toInt())

However, using Long (rather than Int) as the type parameter may, of course, have other repercussions in your code so it’s hardly an ideal solution.


#3

Maybe you need a wrapper class .

class DoubleIndexWrapper<T>(private val di: DoubleIndex<T>) {
    fun selectOrdinal(rowOrdinal: Int): Double = di.select(rowOrdinal)
    fun selectKey(rowKey: T?): Double = di.select(rowKey)
}

#4

What about an (inline) extension method on the generic type. The extension method has no notion of the Int value of the parameter so should be able to resolve to the primitive Int method.