2017-05-11 21 views
4

繼承我有一個接口,是這樣的:元函數檢測模板類通過CRTP

template<typename Concrete, typename T> 
class Interface{ 
    ... 
} 

和混凝土它的實現:

template<typename T> 
class Concrete : public Interface<Concrete<T>, T> 
{ 
    ... 
    using type = typename T; 
} 

我想有一元函數,它可以檢查是否某種類型來自Interface

舉個例子,假設接口只有一個模板參數(因此它不會生孩子的模板類):

template<typename Concrete> 
class A 
{ 
    ... 
} 

class B : public A<B> 
{ 
    ... 
} 
在這種情況下

,我可以使用:

template<typename T> 
struct is_A 
{ 
    static bool const value = std::is_base<A<T>, T>::value; 
} 

我的問題是什麼是最好的方法來產生一個類似的元函數的情況下,有一個額外的模板參數。它應該看起來像:

template<typename T>  
struct is_Interface{} 

要清楚,我可能會產生

template<template <class> class T>  
struct is_Interface 
{ 
    using dummy_type = void; 
    static bool const value = std::is_base<Interface<T<dummy_type>, dummy_type>, T<dummy_type>>::value; 
} 

,但我想,我傳遞的具體類型,而不是模板類的東西。

回答

4

您可以使用重載解析:

template <template <class> class Concrete, class T> 
std::true_type is_Interface_impl(Interface<Concrete<T>, T> *); 

std::false_type is_Interface_impl(...); 

template<typename T> 
struct is_Interface : decltype(is_Interface_impl(std::declval<T*>())) { }; 

衍生 - 底部的指針轉換被允許在模板參數推導,那是怎樣的is_Interface_impl第一過載可以檢測和匹配關係。如果轉換不能發生,SFINAE將應用並且重載分辨率回退到可變參數函數中。

See it live on Coliru!

+0

這真的很酷,它適用於我的情況!非常感謝 – JosephK