If you really wanted to use type parameters only (and be more template-like) you could do it with a macro:
Create the actual macro in a Macro project
import scala.reflect.macros.blackbox
object MyMacroImpl {
def registerMacro[T: c.WeakTypeTag](c: blackbox.Context): c.universe.Tree = {
import c.universe._
val tpe = weakTypeOf[T]
val companion = tpe.typeSymbol.companion
q"""MyMacro.register(${companion.name.toTermName}.componentId)"""
}
Use the macro in your project
class FooComponent
object FooComponent {
val componentId: Int = 1
}
class BarComponent
object BarComponent {
val componentId: Int = 2
}
object MyMacro {
def registerComponent[T]: Unit = macro MyMacroImpl.registerMacro[T]
}
object Main {
def register(id: Int): Unit = println(id)
MyMacro.registerComponent[FooComponent]
}
Edit: Personally, I would just implement it like this:
def register(id: Int): Unit = println(id)
trait HasComponentId {
def componentId: Int
}
class FooComponent
object FooComponent extends HasComponentId {
override val componentId: Int = 1
}
class BarComponent
object BarComponent extends HasComponentId {
override val componentId: Int = 2
}
def registerComponent(comp: HasComponentId): Unit =
register(comp.componentId)
assert(registerComponent(FooComponent) == 1)
No macros (and thus much less complexity), no instantiation of objects and the result is pretty much the same.
FooComponent
inherits the template?? also when you doT::ComponentId
, T does not even haveComponentId
?? you can ignore my question obviously I don't know c++ templates :) – prayagupdregisterComponent<BarComponent>()
will instantiate a function with the bodyregister(BarComponent::ComponentId)
.T
is a stand-in for a type here, not any specific one. – StoryTeller - Unslander Monicatemplate
which has no definition ofComponentId
in it, and it would compile. My guess was template is closer to interface in scala/java/OO, where you predefine what you going to have in your implementation classes. – prayagupd