Difference between using and typedef in C++

Share the Article

Both the keywords can define new types, and both are equally good in standard C++. However, the main difference between using and typedef in C++ specifically relates to templates. Whenever, the program uses templates, the using directive has a clear edge over typedefs declaration. Using is also called alias declaration.

The following simple example illustrates how to use both directives. This program defines same function pointer type in 2 ways. There are no templates here, hence, both directive look similar.

#include <iostream> //main header using namespace std; //namespace void funda(int xvar) { cout << "xvar=" << xvar << endl; } typedef void (*fp)(int); //type with typedef using fa = void (*)(int); //type with using int main() { fp f1 = funda; //typedef type assignment f1(4); fa f2 = funda; //alias type assignment f2(5); return 0; }

The output is similar in both cases.

g++ compilation success with typedef and using declaration

The “using” declaration creates templatized declarations

In above example, “fun” was a normal function. However, when “fun” becomes a template function, things go interesting. Firstly, a typedef cannot define function pointer type because, it is not a single function but a family of functions.

template<typename T> void funda(T xvar) { cout << "xvar=" << xvar << endl; }

In this case, a similar “typedef” declaration may look like as follows. We are trying to create a “templatized” type for pointer to function.

template<typename T> typedef void (*fp)(T);

The compiler shall generate following error:

compiler error : template declaration using typedef with template

With Using declaration

The “using” creates a “templatized” type in same case.

#include <iostream> //main header using namespace std; //namespace template<typename T> void funda(T xvar) { cout << "xvar=" << xvar << endl; } template<typename T> using fa = void (*)(T); //fa is templatized type int main() { fa<int> f2 = funda; //fa initialization with int f2(5); fa<float> f3 = funda; //fa initialization with float f3(5.2); return 0; }

Output:

compilation success with using directive

“Dependent scope” must be used with “typename” keyword

We have seen “Dependent type”. Now, a “Dependent scope” is template where this type is defined. In the following example, A<R>::internal_type is dependent type and this “A<R>” is corresponding dependent scope. Any use of such “dependent type” must precede “typename” keyword. This is necessary to ensure compiler that we know it is actually a type and not something else.

#include <iostream> //main header #include <vector> //for vector stl using namespace std; //namespace template<typename T> class A { T val; public: typedef vector<T> internal_type; }; template<typename R> void funda() { A<R>::internal_type x; //No typename keyword }; int main() { return 0; }

The compiler shall generate an error when “typename” is not present.

c++ compiler error with dependent scope

In above example, internal_type is a type which typedef creates.

template<typename T> class A { T val; public: typedef vector<T> internal_type; //This is type };

However, in one of its instantiation (like, an integer-based instance) of template class, the internal_type may be a vector object and not a type.

template<> class A<int> { int val; public: vector<int> internal_type; //this is object, not type };

When the program uses this integer-based instantiation, then internal_type cannot be used as data type.

#include //main header #include //for vector stl using namespace std; //namespace template class A { T val; public: typedef vector internal_type; //This is type }; template<> class A { int val; public: vector internal_type; //this is object, not type }; template void funda() { A<int>::internal_type xvar; //This is wrong A<float>::internal_type yvar; //This is right }; int main() { return 0; }

The compiler also shall generate error.

c++ compiler error due to not using typename keyword

Same behavior with Using directive

In following example, uses “using” directive to declares type but this also has same limitation as with typedef.

template<typename T> class A { T val; public: using internal_type = vector<T>; //same limitation as typedef };

Main Funda: difference between typedef and using in c++ is almost none, except in one case, where “templatized type” need to be created.

Related Topics:

What are dependent scope type in templates?
What is an implicit interface? 
Calling member functions in template base class
What is template meta programming (TMP)
Concept of Inline Functions
What is reference collapsing?
How std::forward( ) works?
How std::move() function works?
Smart Pointers: shared_ptr <T> 
Smart Pointers: unique_ptr<T>
What is move constructor ?
Understanding Constant Variables


Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *