【问题标题】:Mixing virtual and templates混合虚拟和模板
【发布时间】:2021-12-24 21:06:31
【问题描述】:

我知道在混合继承和模板时存在一些缺陷,但我想知道下面的代码(编译后看起来运行良好)是否“合法”且格式正确。

struct ISession {
    virtual ~ISession() = deafult;
    virtual void run() = 0;
};

template <typename Derived>
struct SessionBase : public ISession {
    SessionBase() {
        static_assert(is_base_of_v<SessionBase<Derived>, Derived>);
    }

    void run() override {
        derived().connect();
    }
    
    Derived& derived() {
        return static_cast<Derived&>(*this);
    }
};

struct PlainSession : public SessionBase<PlainSession> {
    void connect() {
        // do connect plain
    }
};

struct SslSession : public SessionBase<SslSession> {
    void connect() {
        // do connect ssl
    }
};

int main(int argc, char *argv[])
{
    list<unique_ptr<ISession>> sessions;
    sessions.emplace_back(make_unique<PlainSession>());
    sessions.emplace_back(make_unique<SslSession>());
    for_each(sessions.begin(), sessions.end(), [](auto& session) { session->run(); });
}

【问题讨论】:

  • 您指的是哪些陷阱?为什么你认为代码可能有问题?您可以将SessionBase&lt;SslSession&gt; 替换为假设的SessionBase_SslSession,效果大致相同
  • 这是Curiously Recurring Template Pattern (CRTP) 的一个应用程序,乍一看您的代码似乎很好。我只建议添加static_assert 之类的static_assert(std::is_base_of_v&lt;SessionBase&lt;Derived&gt;, Derived&gt;);,以确保不会有人尝试错误地使用SessionBase。编辑:我也会考虑将SessionBase 抽象化。
  • 弗朗索瓦,感谢您的回答和建议!

标签: c++ templates virtual


【解决方案1】:

“陷阱”是您不能拥有一个也是虚拟的成员模板。这将导致未知数量的虚函数,可能会随着类的每次新用途而增加。

template<typename T>
virtual void use(T);   // not possible

只要是任一模板或虚拟,但不是两者都可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    • 2023-04-01
    • 2019-12-15
    • 1970-01-01
    相关资源
    最近更新 更多