【问题标题】:How to enforce contract on template parameter如何在模板参数上强制执行合同
【发布时间】:2020-09-02 12:08:37
【问题描述】:

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

继承接口(抽象基类)

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


    【解决方案1】:

    是的,您可以使用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");
        ...
    };
    

    或使用concept(C++20 起)。

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

    顺便说一句:如果指定了基类baseActionCounterstd::is_base_of 也会返回true;如果这不是您想要的,您可以将条件与std::is_same 结合起来。

    【讨论】:

    • 这很容易。我试试看能不能直接可以baseActionCounter的成员函数。 @songyuanyao,请问你是怎么学模板的?我想知道足够的知识来完成这些基本的逻辑编程任务。我发现的材料通常涉及到论证推导的细节,这太复杂了。
    • @bsobaid 我从C++ 模板:完整指南一书中学习了模板,您可能需要查看book list。 cppreference.com 也很适合学习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 2011-05-04
    • 2015-08-01
    • 2013-12-20
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多