Comme vous le signalez, C++ a des modèles. En bref, C++ dit "il y a un test pour tous les types T tels que Test compile". Cela facilite l'ajout implicite de contraintes sur T, mais elles sont implicites et peuvent être difficiles à comprendre pour un utilisateur de votre classe sans lire le code.
Le polymorphisme paramétrique de Scala (aussi connu sous le nom de génériques) fonctionne beaucoup plus comme ML, Haskell, Java et C#. Dans Scala, quand vous écrivez "class Test [T]" vous dites "pour tout T il existe un type Test [T]" sans contrainte. C'est plus simple à raisonner formellement, mais cela signifie que vous devez être explicite sur les contraintes. Par exemple, dans Scala, vous pouvez dire "test de classe [T <: Foo]" pour dire que T doit être un sous-type de Foo. C# a un moyen d'ajouter une contrainte à T concernant les constructeurs, mais malheureusement Scala ne le fait pas.
Il existe plusieurs façons de résoudre votre problème dans Scala. L'un est typeafe mais un bt plus verbeux. L'autre n'est pas sûr.
La façon dont typesafe ressemble
class Test[T](implicit val factory :() => T) {
val testVal = factory
}
Ensuite, vous pouvez avoir un corps d'usines pour les types utiles dans votre système
object Factories {
implicit def listfact[X]() = List[X]()
implicit def setfact[X]() = Set[X]()
// etc
}
import Factories._
val t = new Test[Set[String]]
Si les utilisateurs de votre bibliothèque ont besoin de leurs propres usines alors ils peuvent ajouter leur propre équivalent de l'objet Factories. Un avantage de cette solution est que n'importe quoi avec une usine peut être utilisé, qu'il y ait ou non un constructeur sans arg.
La façon pas si typesafe utilise la réflexion et une fonctionnalité de Scala appelé manifeste qui sont un moyen de contourner une contrainte Java en ce qui concerne l'effacement de type
class Test[T](implicit m : Manifest[T]) {
val testVal = m.erasure.newInstance().asInstanceOf[T]
}
Avec cette version, vous encore écrire
class Foo
val t = new Test[Foo]
Cependant, s'il n'y a pas à votre disposition constructeur sans arg obtenir une exception d'exécution au lieu d'une erreur de type statique
scala> new Test[Set[String]]
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
Qu'est-ce qu'une question? – stepancheg
Comment est-ce que je fais ce travail? – bsdfish