在 Concept 中使用带有 CRTP 的模板模板参数
Use a template template parameter with CRTP in a Concept
我想写一个 concept
来测试从基础 class 继承。
我的 Base
class 被 Derived
classes 公开继承,使用 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 节第 23 页、template<typename T, typename U> concept bool C3 = true;
中的 Working Paper P0121R0 列表。因此,无论我在哪里读到 concept
can take only one parameter 要么是过时的、错误的,要么是我读得不仔细。 结束编辑
我可以在这里访问我需要的其他类型 T
吗?有没有另一种方法(在我看来,模板类型 D
会携带其类型 T
的信息,但我也不能使用 using T = typename D<T>::valueType;
,因为我需要T
指定 D<T>
的类型...)
我怀疑以下特征应该起作用:
#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(没有概念)
我想写一个 concept
来测试从基础 class 继承。
我的 Base
class 被 Derived
classes 公开继承,使用 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 节第 23 页、template<typename T, typename U> concept bool C3 = true;
中的 Working Paper P0121R0 列表。因此,无论我在哪里读到 concept
can take only one parameter 要么是过时的、错误的,要么是我读得不仔细。 结束编辑
我可以在这里访问我需要的其他类型 T
吗?有没有另一种方法(在我看来,模板类型 D
会携带其类型 T
的信息,但我也不能使用 using T = typename D<T>::valueType;
,因为我需要T
指定 D<T>
的类型...)
我怀疑以下特征应该起作用:
#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(没有概念)