Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

meaning of c++ struct syntax with only typedef

When I examine some code snip from some libraries, I saw some code like this:

template<typename _Function, typename _ReturnType>
struct _TaskOfType_ContinuationTypeTraits
{
    typedef task<typename _TaskTypeTraits<typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType> _TaskOfType;
};

Can someone provide some explanation of the code? What is it trying to do and what is the advantage to use a struct with only typedef statement within the body?

like image 744
user2984297 Avatar asked Sep 06 '25 23:09

user2984297


2 Answers

In C++ parlance, the _TaskOfType_ContinuationTypeTraits is a metafunction. It does type computations at compile-time.

A metafunction is in a way similar to a run-time function. The key difference is that the input arguments to a metafunction are type(s), and returns are also type(s).

Eg. The following metafunction takes a type, and returns a pointer of the type you supply to it.

template <typename T>
struct add_pointer
{
    typedef T* type;
}

Now, if you did add_pointer<int>::type, it returns int*. You see, you gave it a type (int in this case) and the compiler computed a new type (int* in this case) and gave it back to you when you invoked the ::type of the metafunction. When you do ::type on a metafunction, that is when the template is instantiated. This is the run-time equivalent of calling a function. Also note that all of this happened at compile-time!

Now, going back to your _TaskOfType_ContinuationTypeTraits. This is just like my add_pointer. In add_pointer, I just had one template argument, you have two. I just added a pointer to the type that was supplied, you have something much more complicated. But, at it's essence, it is only a type computation. My add_pointer returns when I call ::type on it, yours does when you call ::_TaskOfType.

like image 91
The Vivandiere Avatar answered Sep 09 '25 21:09

The Vivandiere


This kind of syntax is used to create "templated typedefs". In C++11 and above, type aliases / alias templates should be used instead.

The purpose of the code snippet you posted is to create a type alias that depends on _Function and _ReturnType.

It can be accessed like this:

typename _TaskOfType_ContinuationTypeTraits<F, R>::_TaskOfType

If you have access to C++11, this is a cleaner, better and more straightforward solution:

template<typename _Function, typename _ReturnType>
using _TaskOfType = 
    task<typename _TaskTypeTraits<
        typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType>

Which can be used like this:

_TaskOfType<F, R>

More info: "Difference between typedef and C++11 type alias"

like image 25
Vittorio Romeo Avatar answered Sep 09 '25 22:09

Vittorio Romeo