2016-08-24 87 views
2

我需要轉換這個鑄造元函數「有限的」元函數到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; 
}; 

我attampts做如下:

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’

很多感謝提前給任何願意幫助的人...

回答

2

您當前的代碼不起作用,因爲部分專業化爲<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

+0

真棒!這工作完美。很多thannks TartanLlama! –