对于以下类型系统,
template <typename U, typename V>
struct Base { ... };
struct Derived1 : Base<TypeA, TypeB> { ... };
struct Derived2 : Base<TypeA, TypeC> { ... };
我希望能够编写接受从
Base
派生的参数的函数,同时限制 Base
中的一些(无,全部)模板参数。我的想法是为此使用 C++ 概念(尽管我对其他方法持开放态度!)。本质上,我正在寻找类似的东西
template <typename T, typename U, typename V>
concept FromBase = requires ...
这样我就可以编写这样的函数
void foo(FromBase auto param); // accepts anything derived from `Base`
void bar(FromBase<TypeA> auto param); // accepts `Derived1` and `Derived2`
void baz(FromBase<TypeA, TypeB> auto param); // accepts `Derived1`, but not `Derived2`
我如何用概念来做到这一点?或者这对于 C++ 来说是可能的吗?请注意,我专门寻找一种“眼睛和头脑都轻松”的解决方案,即理想情况下我不想使用 N 个不同的概念来支持 N 个潜在参数。
额外问题:这对于
Base
中的混合类型/非类型模板参数也可能吗?
标题已经准备好construct -
std::derived_from
,如果我正确理解意图的话。现在我们只需用可变参数表达式替换类型:
#include <concepts>
// placeholders
struct TypeA {}; struct TypeB {}; struct TypeC {};
template <typename U, typename V>
struct Base { };
struct Derived1 : Base<TypeA, TypeB> { };
struct Derived2 : Base<TypeA, TypeC> { };
template<class Derived, typename ...Args>
concept FromBase = std::derived_from<Derived, Base<Args ...>>;
void foo(FromBase auto param); // accepts anything derived from `Base`
void bar(FromBase<TypeA> auto param); // accepts `Derived1` and `Derived2`
void baz(FromBase<TypeA, TypeB> auto param); // accepts `Derived1`, but not `Derived2`
int main()
{
Derived1 d1;
Derived2 d2;
baz(d1);
// will not compile
// baz(d2);
}