使用可变参数模板标记转换元函数

Tag casting meta function using variadic templates

我需要使用可变参数模板将此 "limited" 元函数转换为 C++11 样式:

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).

我需要此演员表按类型进行标签分派,如此处发布: http://barendgehrels.blogspot.de/2010/10/tag-dispatching-and-inheritance.htmlhttp://barendgehrels.blogspot.de/2010/10/tag-dispatching-by-type-tag-dispatching.html

原始版本(可用但数量有限 类 (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;
};

我的尝试如下:

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;
};

当我尝试使用它时:

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;

它抱怨未定义类型 属性:

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

非常感谢任何愿意提供帮助的人...

您当前的代码不起作用,因为偏特化是针对 <TAG,void>,但您最终得到的 void 数量等于基础 类 的数量。

我宁愿将主模板作为基本案例,并使递归案例成为部分特化

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

template<typename TAG, typename BASE_TAG, typename ... OTHER_BASE_TAGS>
struct tag_cast<TAG, BASE_TAG, OTHER_BASE_TAGS...>
{
    using type = typename std::conditional<
                     std::is_base_of<BASE_TAG, TAG>::value, 
                     BASE_TAG, 
                     typename tag_cast<TAG, OTHER_BASE_TAGS ...>::type
                 >::type;
};

Live Demo