Simply speaking, template argument type deduction only works to the right of the last ::
, if there is one. Imagine what you're telling the compiler:
I am calling foo()
with a certain type. Now I want you to look at all single-parameter class templates which could possibly exist, try to instantiate each of them with all possible types, and see for which of these a nested typedef iterator
matches the type I sent to foo
. Then use that combination as template arguments.
I believe it's pretty obvious that doesn't work. That's why anything to the left of ::
is a non-deduced context, so template parameters in such context don't participate in template argument deduction. And since foo
offers no other context, the argument cannot be deduced.