1

The following code

template <typename T, class ContainerType>
ContainerType<T>::iterator elementIteratorAt(ContainerType<T> container, size_t index)
{
    return container.end();
}

generates a compile error at the function's return type (ContainerType<T>::iterator):

error C2988: unrecognizable template declaration/definition

Why does it happen and how to write this properly? I'm not even instantiating the template, just compiling.

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • That's a function template, not a template function, by the way. Anyway, see [Where and Why Do I Have to Put the Template and Typename Keywords](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords). – chris Jun 13 '14 at 17:35
  • @chris: Hm. In my language that certainly is "template function". – Violet Giraffe Jun 13 '14 at 17:40
  • 2
    @VioletGiraffe No, it's definitely a *function template*. Similarly, there are *class templates* but no *template classes* – Praetorian Jun 13 '14 at 17:46
  • @Praetorian: maybe you're right for English terminology, I'll read on it. Just explaining why I wrote it the way I did. Makes more sense this way, too. It's a function of a template kind; primarily a function, then a template. Anyway, I still can't make my code compile after reading the question you deem a duplicate. – Violet Giraffe Jun 13 '14 at 17:51
  • @VioletGiraffe Yeah, sorry about that. Reopened now, there's another problem with your code. – Praetorian Jun 13 '14 at 17:52
  • @Praetorian: P. S. It's embarassing to see that I've already upvoted the linked question and its top rated answer, meaning I've already been down that road some time ago... – Violet Giraffe Jun 13 '14 at 18:03
  • 1
    @VioletGiraffe That's happened to me a few times too :) – Praetorian Jun 13 '14 at 18:04

2 Answers2

3

There are two problems with your code. First, ContainerType<T>::iterator is a dependent type so you must add the typename keyword. Next, ContainerType is supposed to be a template, but the template parameter doesn't indicate that. You need a template template parameter.

template <typename T, template<class...> class ContainerType>
typename ContainerType<T>::iterator 
    elementIteratorAt(ContainerType<T> container, size_t index)
{
    return container.end();
}

Live demo

I've made the template template parameter variadic because containers in the standard library all have more than one template parameter.


As suggested in the comments, you could also simplify it to

template <class ContainerType>
typename ContainerType::iterator 
    elementIteratorAt(ContainerType container, size_t index)
{
    return container.end();
}

Use ContainerType::value_type (will work for standard library containers) if you need access to the element type in the container.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
0

You need the typename keyword anytime you have a dependent type (such as ContainerType<T>::iterator):

template <typename T, class ContainerType>
typename ContainerType<T>::iterator elementIteratorAt(ContainerType<T> container, size_t index)
Adam
  • 16,808
  • 7
  • 52
  • 98