Search code examples
c++templatestypename

Template member function syntax


I'm currently implementing containers in C++ and I have a question about the syntax used to declare member functions.

I have a Vector_declaration.hpp file where I declare the vector class and all its components for instance: reference operator[](size_type n); Where reference is defined by typedef typename Allocator::reference reference;

In another file called vector.hpp I want to implement the elements defined in Vector_declaration.hpp and I found that the only way to do that was with the following syntax:

template <typename T, typename Allocator>
typename vector<T, Allocator>::reference
vector<T, Allocator>::operator[](size_type n)

I don't understand what role typename vector<T, Allocator>::reference plays here, why do I have to rewrite the typename each time I use it in a function, shouldn't I be able to just use the word reference instead? Is there anyway to do so, so the code would be cleaner?


Solution

  • Here:

    template <typename T, typename Allocator> 
    typename vector<T, Allocator>::reference 
    vector<T, Allocator>::operator[](size_type n);
    

    The typename vector<T, Allocator>::reference is the return type of the method. Consider how it would look without templates:

    struct foo {
       using reference = int&;
       reference bar();
    };
    
    foo::reference foo::bar() { /*...*/ }
    

    reference is declared in the scope of foo. If you want to refer to it outside of the scope of foo you need to qualify the name foo::reference. Because this:

    reference foo::bar() { /*...*/ }
    

    would result in an error: "reference is not declared".

    Moreover, typename is needed because vector<T, Allocator>::reference is a dependent name (ie you need to tell the compiler that it is a type, in a specialization it might be the name of a member or not exist at all).