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<Derived, Base>
の判定とは異なる結果となる。
例
#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 and T are others" << 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>();
}
44
#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 and T are others" << std::endl;
}
struct Base {};
//public継承
struct Derived1 : Base {};
出力
U and T are others
U is base class of T
U is base class of T
U and T are others
U and T are others
U and T are others
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 ✅