2015-10-21 79 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

相关问题