One of the biggest problems I have with C++ templates is duck-typing and that the requirement of the type parameters is not encoded except in the code of the template. I have yet to get decent error messages when I mess up the implicit contracts.
Mostly because they miss something like concepts (or what I think concepts should be) where you can name a group of requirements and check that a template definition stays within the requirements (which makes sure the template can actually be instantiated) and that a type parameters fits within the requirements and the compiler can just say "type Foo doesn't follow concept Bar because ..." instead of some semi-related error because a function doesn't return the correct type resulting in another function call being unable to be resolved or something like that.
For example with an iterable thing you could create a concept Iterable with 1 requirement: if you have a variable a of a type that follows the Iterable concept you can call iterator(a) and it returns a value of a type that follows the Iterator concept. The Iterator concept then has 3 functions it should require: finished(it) -> bool, advance(it)->void, element(it)-> Element.
Though from this point the type parameter could be expanded to include the specific functions required in case the user doesn't want to follow your naming conventions.