Home > Back-end >  Template member function syntax
Template member function syntax

Time:10-18

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?

CodePudding user response:

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).

CodePudding user response:

With trailing return type (C 11), you might do:

template <typename T, typename Allocator>
auto vector<T, Allocator>::operator[](size_type n)
-> reference
{
// ...
}

Before vector<T, Allocator>::, you are not yet in scope class, so writing just reference would refer to the one in global scope (::reference).

So you can use types/using from the class in parameters and trailing return type (and in scope of the function).

  • Related