Search code examples
c++templatestypename

The 'typename' word in C++


I am reading a C++ code and I came across the use of the keyword typename in the middle of the class definition.

Here is the class definition and the keyword is used in the protected section.

template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
class CBoundary
{
    typedef CLoop<CVertex,CEdge, CFace, CHalfEdge> TLoop;

public:

    CBoundary( CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * pMesh );

    ~CBoundary();

    std::vector<TLoop*> & loops() 
    { 
        return m_loops; 
    } 

protected:

    CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * m_pMesh;

     typename std::vector<TLoop*> m_loops;

    void _bubble_sort( std::vector<CLoop<CVertex, CEdge, CFace, CHalfEdge>*> & loops);
};

Is this the same as the typedef keyword? There seem to be a couple of related questions like so but I did not really understand the explanation there.

In fact since typename is one of the SO tags I will list the explanation which I did not understand

typename is a keyword in the C++ programming language with two meanings. First, it can be used to declare type arguments inside a template declaration, and is synonymous with "class." Second, it can be used to indicate that a dependent name refers to a type. A common cause of errors in C++ code is the omission of an essential typename.

It looks like I am dealing with the second use here. But I don't understand what "dependent name" means here.

I am just a beginner in template metaprogramming with C++ so a simple explanation of the use in the class above would be very helpful.


Solution

  • In simple words, "dependent name" in a template code is some type which is constructed within the definition of the template.

    In your example, the types CVertex, CEdge, CFace, CHalfEdge are template parameters. All other names which are declared with usage of the parameters are dependent.

    They can be type names but can be something else, e.g. name of the functions or variables. Compiler has to understand, whether a given dependent name is a type or a variable. It is actually compiler-dependent. To help the compiler, you add "typename" to indicate that this identifier is a type.

    Imagine, that your code does not have #include <vector> but instead uses forward declaration: namespace std { template<class T, class Alloc=allocator<T> > class vector; }

    Then compiler has no idea which names within class vector are types and which are member names. It only knows that vector is a type.

    For example, in the code typename std::vector<TLoop*> m_loops; most likely the word typename can be omitted for most compilers because they know that vector is a type.

    However, the code std::vector<TLoop*>::const_iterator will sure require typename: for (typename std::vector<TLoop*>::const_iterator it = loops().begin(); ...

    Hope it helps.