In depth understanding of class and typename in c++ templates

  • 2020-05-26 09:40:00
  • OfStack

preface

The borrowed "Effective STL" has been on the shelf for a long time. Considering that during this period of time, I was either writing lua to do business or learning android to prepare for business, I haven't seen c++ for a long time. In order not to lose the old shop, also in order to hurry to return the book to more people to read. I decided to start over and read it.

The difference between class and typename is used in templates

I hadn't turned the page for a few pages when I saw this code. In the impression last time also saw here 1 now did not understand, also specially searched. And I forgot it when I tried it again. As expected, a good memory is not as good as a rotten pen, write a blog mark1.

This is where the author declares templates using typename instead of class. In general, using typename or class is just a matter of coding style. However, when dealing with a dependent type (dependent type), typename must be used instead of class in order to avoid the potential precautionary parsing 2 semantics.


template<typename C>
bool lastGreaterThanFirst(const C& container)
{
 if(container.empty()) return false;

 typename C::const_iterator begin(container.begin());
 typename C::const_iterator end(container.end());
 return *--end > *begin;
}

The key here is these two lines:


typename C::const_iterator begin(container.begin());
typename C::const_iterator end(container.end());

If the typename keyword is not used


template<typename C>
bool lastGreaterThanFirst(const C& container)
{
 if(container.empty()) return false;

 C::const_iterator begin(container.begin());
 C::const_iterator end(container.end());
 return *--end > *begin;
}

(" Effective STL "points out that some compilers mistakenly accept code without typename, but such code is not portable):


test.cpp:6:2: error: missing 'typename' prior to dependent type name 'C::const_iterator'
 C::const_iterator begin(container.begin());
 ^~~~~~~~~~~~~~~~~
 typename
test.cpp:7:2: error: missing 'typename' prior to dependent type name 'C::const_iterator'
 C::const_iterator end(container.end());
 ^~~~~~~~~~~~~~~~~
 typename
2 errors generated.

If you are using class here instead of typename you will report an error:


test.cpp:8:11: error: elaborated type refers to a typedef
 class C::const_iterator begin(container.begin());
   ^
test.cpp:15:2: note: in instantiation of function template specialization 'lastGreaterThanFirst<std::__1::vector<int, std::__1::allocator<int> > >' requested here
 lastGreaterThanFirst(vec);
 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:476:54: note: declared here
 typedef __wrap_iter<const_pointer>  const_iterator;
       ^
1 error generated.

Why do you need typename for dependent types

So let's do this step by step.


ClassA::foo

When you look at the code above, what do you think foo is? The first reaction is going to be a static member variable of ClassA, right?

So when you go back and you see the code below, what is a?


ClassA::foo a;

a is a variable of type ClassA::foo,ClassA::foo is an inner class:


class ClassA {
public:
 class foo {
 };
};

Or one typedef inside ClassA:


class ClassA {
public:
 typedef int foo;
};

When foo is an inner class of ClassA or an inner typedef,foo is a dependent type.

For C::const_iterator,const_iterator may be a static member variable of C or a dependent type of C. By default, the compiler resolves it to a variable, so typename needs to tell the compiler that it is a type:


typename C::const_iterator begin(container.begin());

A special case of typename is not required when a dependent type occurs

There is no need to use the typename keyword to indicate that a dependent type is of type 1 when encountering a list of base classes that appear in the class template definition:


typename C::const_iterator begin(container.begin());
typename C::const_iterator end(container.end());
0

Because there must be one type in the base class list.

conclusion


Related articles: