namespace std {
template <class Derived, class Base>
concept derived_from =
is_base_of_v<Base, Derived> &&
is_convertible_v<const volatile Derived*, const volatile Base*>;
}
概要
derived_fromは、型DerivedがBaseから派生していることを表すコンセプトである。
備考
derived_from<Derived, Base>は以下のどちらかの場合にのみ満たすことができる。
BaseはDerivedの曖昧ではないpublic継承されたクラスであるBaseとDerivedはCV修飾の違いを除いて同じクラス型である
DerivedがBaseを公開継承しない場合、std::is_base_of<Base, Derived>の判定とは異なる結果となる。
例
#include <iostream>
#include <concepts>
template<typename T, typename U>
requires std::derived_from<T, U>
void check_derived() {
std::cout << "U is base class of T" << std::endl;
}
template<typename T, typename U>
void check_derived() {
std::cout << "U is not base class of T" << std::endl;
}
struct Base {};
//public継承
struct Derived1 : Base {};
//private継承
struct Derived2 : private Base {};
//protected継承
struct Derived3 : protected Base {};
//曖昧な継承
struct Derived4 : Base, Derived1 {};
//仮想継承
struct Derived5 : virtual public Base {};
struct Derived6 : virtual public Base {};
struct Derived7 : Derived5, Derived6 {};
//継承の継承
struct Derived8 : Derived1 {};
int main()
{
check_derived<int, int>();
check_derived<Base, const Base>();
check_derived<Derived1, Base>();
check_derived<Derived2, Base>();
check_derived<Derived3, Base>();
check_derived<Derived4, Base>();
check_derived<Derived5, Base>();
check_derived<Derived7, Base>();
check_derived<Derived8, Base>();
}
出力
U is not base class of T
U is base class of T
U is base class of T
U is not base class of T
U is not base class of T
U is not base class of T
U is base class of T
U is base class of T
U is base class of T
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 3 ✅