首页 > 解决方案 > 如何在模板参数上强制执行合同

问题描述

如何将模板参数指定为某种类型,即它必须已实现接口(模板参数必须是特定基类的派生类)

继承人接口(抽象基类)

class baseActionCounter{
public:
virtual int eat()=0;
virtual int drink()=0;
};

现在我希望我的模板参数是 baseActionCounter 类型

这是模板类

//imaginary template syntax in the line below. Is there a way of achieving this behavior?
template <class counterType : baseActionCounter>

    class bigBoss{
    counterType counter;
    public:
    int consumerStats(){
    //I am able to call member function because I know that counter object has eat() and drink() 
    //because it implemented baseActionCounter abstract class
    return counter.eat() + counter.drink(); 
    }
    };

我也可以从 baseActionCounter 派生我的 bigBoss 类,但我想知道如何使用模板实现这种行为。此外,模板专业化也不适合,因为对于 baseActionCounter 类的任何实现者只有一个 BigBoss 类。

标签: c++templates

解决方案


是的,您可以使用std::is_base_of来检查类型,例如

template <class counterType, std::enable_if_t<std::is_base_of_v<baseActionCounter, counterType>>* = nullptr>
class bigBoss {

或者

template <class counterType>
class bigBoss {
    static_assert(std::is_base_of_v<baseActionCounter, counterType>, "counterType must derive from baseActionCounter");
    ...
};

或使用概念(C++20 起)。

template <class T>
concept Derived = std::is_base_of_v<baseActionCounter, T>;

template <Derived counterType>
class bigBoss {

BTW:如果指定了基类,std::is_base_of也返回;如果这不是您想要的,您可以将条件与.truebaseActionCounterstd::is_same


推荐阅读