2015-10-21 76 views
3

我想編寫一個測試從基類繼承的concept在Concept中使用帶CRTP的模板模板參數

我的Base類是由Derived類使用CRTP公開繼承的。

此代碼工作正常:

#include <type_traits> 
namespace NS 
{ 
    template<typename D> 
    class Base { 
     // ... 
    }; 

    class Derived : public Base<Derived> 
    { 
    public: 
     constexpr Derived() = default; 
     // ... 
    }; 
} 

template<typename D> 
concept bool inheritsFromB() { 
    return std::is_base_of<NS::Base<D>, D>::value; 
} 

template<inheritsFromB b> 
void myFunct() {}; 

int main() { 
    constexpr auto d = NS::Derived(); 
    using dType = typename std::decay<decltype(d)>::type; 
    myFunct<dType>(); 
} 

我打了一個問題,如果我想模板Derived。這可能嗎?

namespace NS 
{ 
    template<typename D, typename T> 
    class Base { ... }; 

    template<typename T> 
    class Derived : public Base<Derived<T>, T> 
    { // ... 
     // probably some using declaration for T? 
    }; 
} 

template<template <typename> class D> 
concept bool inheritsFromB() { 
    return std::is_base_of<NS::B<D<T>,T>, D<T>::value; 
} 

... 

明顯的問題是,我有我的concept聲明沒有T。 此外,我敢肯定,我不能宣佈

template<template <typename> class D, typename T> 
concept bool inheritsFromB() { 
... 
} 

因爲 concept需要一個模板參數。

編輯 - 在第8.3.5節,P23template<typename T, typename U> concept bool C3 = true;Working Paper P0121R0名單。因此,無論我在哪裏閱讀concept只能使用一個參數,都是過時的,錯誤的,或者我認爲它不夠用。 結束編輯

我可以訪問我需要的其他類型T嗎?有沒有其他的方法(在我看來,像模板類型D將攜帶它是什麼類型的信息是T是,但我也不能使用using T = typename D<T>::valueType;,因爲我需要T具體的類型D<T> ...)

回答

2

我懷疑以下特點應該工作:

#include <type_traits> 
#include <utility> 

namespace NS 
{ 
    template <typename D, typename T> 
    class Base {};  
    template <typename T> 
    class Derived : public Base<Derived<T>, T> {}; 
} 

namespace detail 
{ 
    template <typename T, template <typename> typename D> 
    std::true_type is_derived_from_base(const ::NS::Base<D<T>,T>*); 
    std::false_type is_derived_from_base(void*); 
} 

template <typename T> 
using is_derived_from_base = decltype(detail::is_derived_from_base(std::declval<T*>())); 

template <typename T> 
concept bool inheritsFromB() 
{ 
    return is_derived_from_base<T>{}; 
} 

DEMO(不含概念)

+0

看起來不錯 - 我嵌套在'detail'命名空間中'NS'然後移動'使用is_derived_from_base'聲明進入'NS'也,這樣我的con cept現在使用'NS :: is_derived_from_base'。感謝你的回答! – chrisb2244

相關問題