C++ - 使用基类作为模板参数

标签 c++ oop templates

我希望我的模板函数只接受从基类继承的类作为参数。我认为代码片段可以更好地解释它。

class Base
{
    // Some magic
}

class Derived : public Base
{
    // Even more magic
}

class Foo
{}

// Is it possible to tell template to accept only classes derived from Base?
template<class T>
do_something(T obj)
{
    // Perform some dark magic incantations on obj
}

int main()
{
    Foo foo;
    Derived derived;
    do_something<Derived>(derived); // Normal
    do_something<Foo>(foo); // Compilation error if I understand templates correctly
}

最佳答案

C++20 之前的版本您可以使用 enable_if加上检查is_base_of :

template<class T, std::enable_if_t<std::is_base_of_v<Base, T> && !std::is_same_v<Base, T>, int> = 0>
void do_something(T obj)
{
    // Perform some dark magic incantations on obj
}

请注意,我已明确禁止该类型成为 Base 的实例(因为 is_base_of 认为类型是其自身的基础)。如果您想允许 Base 的实例,然后删除 && !std::is_same_v<Base, T>

Live Demo


在 C++20 中,我们几乎可以直接翻译 enable_if进入requires表达式:

template<class T>
requires (std::is_base_of_v<Base, T> && !std::is_same_v<Base, T>)
void do_something(T obj)
{
   // ...
}

Concepts Demo

或者,如果您想允许 Base 的实例,您可以使用内置的derived_from概念:

template<class T>
requires std::derived_from<T, Base>
void do_something(T obj)
{
   // ...
}

Concepts Demo 2

关于C++ - 使用基类作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65570033/

相关文章:

c++ - 函数模板重载解析在 Visual C++ 2017 中失败

c++ - 在 C++ Windows 10 桌面应用程序中获取 BLE 信标

c++ - 多线程无法正常加入

java - 如何在java泛型中为类型参数定义静态字段

oop - Scala中有类方法之类的东西吗?

c++ - 是否可以在以下代码中避免对复制/移动构造函数的需要?

c++ - 从另一个类访问 long

c++ - 在另一个类方法中运行类方法

java - 将文件内容复制到链表数组中并对其进行排序

c++ - 重载 operator= 在模板类中