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