mercredi 24 août 2016

Tag casting meta function using variadic templates

I need to convert this "limited" metafunction into C++11 style using variadic templates:

The goal is to implement a meta function which casts the given TAG into the BASE_TAG recursively though all the base tags given. If no base class matches, no cast is performed (the result of the cast is the original TAG type).

This cast I need for Tag dispatching by type as published here: http://ift.tt/2bfTwXX and http://ift.tt/2beyr5Z

Original version (working but limited in number of base classes (BTx)):

template<typename TAG, typename BASE_TAG, typename BT2 = void, typename BT3 = void, typename BT4 = void, typename BT5 = void, typename BT6 = void, typename BT7 = void>
struct tag_cast
{
    using type = typename std::conditional<std::is_base_of<BASE_TAG, TAG>::value, BASE_TAG, typename tag_cast<TAG, BT2, BT3, BT4, BT5, BT6, BT7, void>::type>::type;
};
template<typename TAG>
struct tag_cast<TAG, void, void, void, void, void, void, void>
{
    using type = TAG;
};

My attampts to do it follows:

template<typename TAG, typename BASE_TAG, typename ... OTHER_BASE_TAGS>
struct tag_cast
{
    /* If TAG is derived from BASE_TAG, set type to BASE_TAG. Search in other base tags if specified (or set the type to itself if not found anywhere) */
    using type = typename std::conditional<std::is_base_of<BASE_TAG, TAG>::value, BASE_TAG, typename tag_cast<TAG, OTHER_BASE_TAGS ..., void>::type>::type;
};

template<typename TAG>
struct tag_cast<TAG, void>
{
    using type = TAG;
};

When I try to use that:

class BaseTag1 {};
class BaseTag2 {};
class BaseTag3 {};
class BaseTag4 {};

class Tag1 : BaseTag1 {};

/* Dispatch the tag */
using ToothProfileTag = typename tag_cast<Tag1, BaseTag1, BaseTag2, BaseTag3, BaseTag4>::type;

it complains about type property not being defined:

error: no type named ‘type’ in ‘struct tag_cast’

Many thanks in advance to anyone willing to help...

Aucun commentaire:

Enregistrer un commentaire