[英]How to define a template function that only accepts a base class with parameter T of type its subclass?
It is not specific to casting.它不特定于铸造。 My scenario is how to define a template function that only accepts a base class for parameter
T
of type subclass.我的场景是如何定义一个模板 function,它只接受一个基类 class 作为子类类型的参数
T
template<typename T> // T must be a subclass
T* DoSomething(<I don't know> parent) // parent must be a base class
{
// here the specified subclass of type T is produced.
// return object of type T which is a subclass.
}
A contrived usage:人为的用法:
Parent* p = new Child();
Child* c = DoSomething<Child>(p);
delete p;
One way could be by using std::is_base_of
or std::is_base_of_v
in combination with a static_assert
:一种方法是将
std::is_base_of
或std::is_base_of_v
与static_assert
结合使用:
template<typename Derived, typename Base>
Derived* CastChecked(Base* parent)
{
static_assert(std::is_base_of_v<Base,Derived>);
return dynamic_cast<Derived*>(parent);
}
As you are not specifying a language version, I want to add the C++20 and beyond way is to use concepts.由于您没有指定语言版本,我想添加 C++20 及以后的方法是使用概念。 Your case is actually shown as an example on cpp reference .
您的案例实际上显示为cpp reference 上的示例。
For your case对于你的情况
#include <type_traits>
// concept
template <class D, class B>
concept Derived = std::is_base_of_v<B, D>;
template <typename D, typename B>
requires Derived<D, B>
D* CastChecked(B* parent) {
return dynamic_cast<D*>(parent);
}
struct Foo {};
struct Bar : Foo {};
struct Baz {};
int main() {
auto foo{Foo{}};
Bar* bar{&foo};
auto const r1{CastChecked<Foo>(bar)};
// auto const r2{CastChecked<Baz>(bar)}; fails
}
However, you don't have to roll your own concept, as there's already a concept in the standard library: std::derived_from
.但是,您不必推出自己的概念,因为标准库中已经有一个概念:
std::derived_from
。 So you can just write:所以你可以写:
#include <concepts>
template <typename D, typename B>
requires std::derived_from<D, B>
D* CastChecked(B* parent) {
return dynamic_cast<D*>(parent);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.