【问题标题】:C++ - using base class as template parameter [duplicate]C ++ - 使用基类作为模板参数[重复]
【发布时间】:2021-01-05 05:42:22
【问题描述】:

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

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 吗?
  • @AndyG C++ 17 我想只有
  • 应该do_something 允许Base 本身的实例吗?

标签: c++ oop templates


【解决方案1】:

Pre-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 的实例,则删除 &amp;&amp; !std::is_same_v&lt;Base, T&gt;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 2014-04-18
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多