Tag Archives: Using

Typedef super

A useful addition to a derived class is a typedef aliasing the base class as super:

class Derived : public Base
{
private:
    typedef Base super;
};

This allows you to use super to call the base class constructor from the derived class:

    Derived(int i, int j)
        : super(i), j_(j)
    {
    }

You can also use super to call the base class version of a virtual function in a derived class override:

 virtual void Show()
{
    super::Show();
    std::cout << "Derived Show()\n";
}

It means that if you need to add another layer of inheritance, you only need to change the inheritance part of the class declaration and this typedef.

class Derived : public Intermediate
{
private:
    typedef Intermediate super;
};

You should make the typedef private, to prevent it from being inherited and accidentally used from derived classes that do not declare it.

Visual C++ has a non-standard extension __super: __super.

It is available in Java: Using the Keyword super.

Nowadays you should probably use using:

class Derived : public Base
{
private:
    using super = Base;
};

So it should probably be called the "using super =" idiom.

Template specialisation with a non-type template parameter

The problem

Say you have a generic matrix class like this with non-type template parameters for the number of rows and columns:

template <typename ElementType, size_t Rows, size_t Columns>
class Matrix
{
    ElementType entries_[Rows][Columns];
    // etc...
};

You would like to create a specialization for a column vector, where the number of columns is always 1. However, the following typedef doesn’t compile:

typedef Matrix<size_t, Rows, 1> ColumnVector;

C++03

In C++03, you have 2 options.
Firstly, you can use inheritance:

template <typename ElementType, size_t Rows>
class ColumnVector : public Matrix<ElementType, Rows, 1>
{
};

Secondly, you could use a class with a nested typedef:

template <typename ElementType, size_t Rows>
struct ColumnVector
{
    typedef Matrix<ElementType, Rows, 1> type;
};

In this case, you could declare a column vector with:

ColumnVector<int, 3>::type vec;

C++11

In C++11, you can use an alias declaration to solve the problem more neatly:

template <typename ElementType, size_t Rows>
using ColumnVector = Matrix<ElementType, Rows, 1>;

This is a good example of how much more powerful the new alias declarations with using are than typedefs.

typedef and using

One of the nicer new features in C++11 is the extension of the using keyword in an alias-declaration so that it is now equivalent to typedef in all cases.

This means that code like this:

template <class T>
class C
{
    typedef typename T::U V;
};

Can be written like this:

template <class T>
class C
{
    using V = typename T::U;
};

Function pointers also look much better:

typedef void(pfn*)(const C&);

Becomes:

using pfn = void(*)(const C&);