【问题标题】:Generating pure virtual functions and implementations from type list从类型列表生成纯虚函数和实现
【发布时间】:2021-03-11 11:15:29
【问题描述】:

让我们想象一下简单的类型列表:

template<typename...Types>
struct TypeList
{}

我想使用这样的类型列表为每种类型在单个接口中生成 N 个虚函数,并在单个 impl 类型中生成 N 个实现,它可以衰减到接口。

我的尝试:

template<typename Type>
struct Itf_SingleType
{
    virtual void process(const Type&) = 0;
};

template<typename...>
struct Itf;

template<typename...Types>
struct Itf<TypeList<Types...>> : Itf_SingleType<Types>...
{
    using Itf_SingleType<Types>::process...;
    virtual ~Itf() = default;
};

此时我在接口中有 N 个虚函数。但我在附加实现时遇到问题:

template<typename Type>
struct Impl_SingleType
{
   void process(const Type&)
   {
        //can be anything at this point, so let it be this:
        puts(__PRETTY_FUNCTION__);
   }
};

template<typename...>
struct Impl;

template<typename...Types>
struct Impl<TypeList<Types...>> : Itf<TypeList<Types...>>, Impl_SingleType<Types>...
{
    using Impl_SingleType<Types>::process...;
};

魔杖盒示例:https://wandbox.org/permlink/s0n1DX7t7we8d6mM

但是我仍然遇到两个错误:

  1. 不知道为什么它不能在process(7)process(const std::string&amp;) 之间进行选择。 通过将using Itf_SingleType&lt;Types&gt;::process...; 添加到Itf 来修复

  2. 不知道为什么尽管在Impl 中声明了using,但它仍然认为它没有超载

我们可以假设支持 C++17。

【问题讨论】:

  • 我们不能被兄弟类覆盖。虚拟继承可以Demo吗?

标签: c++ templates c++17 variadic-templates


【解决方案1】:

Itf_SingleType::process 不会覆盖Itf_SingleType::process,因为这两个类是不相关的。从两者继承的类将仅具有两个不同的不相关函数,名为process,具有相同的签名。以下是解决此问题的方法:

template<typename...Types>
struct Itf<TypeList<Types...>> : virtual Itf_SingleType<Types>... // virtual!
...

template<typename Type>
struct Impl_SingleType : virtual Itf_SingleType<Type> // <- virtual!
{
   void process(const Type&) override // now we override
   {
   }
};

【讨论】:

  • 我们可能会在 OP 的链接中注意到关于 Impl&lt;ExampleTypeList&gt; 的错误仍然是抽象的。
【解决方案2】:

如果某个成员函数 vf 在类 Base 中声明为 virtual,并且某个直接或间接从 Base 派生的类 Derived 具有相同的成员函数声明

  1. 姓名
  2. 参数类型列表(但不是返回类型)
  3. cv 限定符
  4. 引用限定符

那么Derived 类中的这个函数也是virtual(无论关键字virtual 是否在其声明中使用)并且覆盖Base::vf(无论在其声明中是否使用了 override 这个词)。

基类Base 的虚拟成员函数vf最终覆盖器,除非派生类声明或继承(通过多重继承)另一个函数覆盖vf

抽象类是一个定义或继承至少一个final overrider纯虚函数的类.

事实上,Impl 是一个抽象类,因为它的 最终覆盖器 process 仍然是纯虚拟。 (我提到的process 是指process&lt;T&gt; 的任何实例化。)

为什么?因为Impl_SingleType 没有继承Itf_SingleType,所以Impl_SingleType::process 不会覆盖纯虚函数声明Itf_SingleType::process。所以Impl::process(它不存在)和Impl_SingleType::process都不能覆盖Itf_SingleType::process最终覆盖器实际上是Itf_SingleType::process 本身!

所以要让这段代码有效,你应该让Impl_SingleType继承Itf_SingleType

【讨论】:

    猜你喜欢
    • 2016-02-18
    • 2018-10-14
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2013-12-31
    相关资源
    最近更新 更多