当前位置: 首页 > 知识库问答 >
问题:

如何根据模板类型启用继承开关

喻增
2023-03-14

我想根据传递给类的模板参数实现一个实现开关:

  • 如果传递的模板类型派生自特定类(此处:Serializable),则创建该类型实例的容器DataElement应派生自SerializableElement,并重载从其继承的两个纯虚拟方法(此处:unloadTo和loadFrom)
  • 然而,如果传递的模板类型不是从Serializable派生的,那么DataElement不应该从SerializableElement派生,因此不应该重载纯虚拟方法

我对代码进行了调整,使其能够隐藏类数据元素中的类方法,方法如下:基于布尔模板参数的Enable方法

不过,当我根据自己的问题调整技巧时,确实会出现以下错误:

错误:无法将变量“dataEle”声明为抽象类型“DataElement”

可测试的。H

#ifndef TESTENABLEIF_H_
#define TESTENABLEIF_H_


#include <iostream>
#include <type_traits>

/// @brief  some dummy class to mark a type as Serializable
class Serializable {};

/// @brief abstract base class which adds additional abilities to DataElement
class SerializableElement {
public:
    virtual void unloadTo(int x) =0;
    virtual void loadFrom(int x) =0;
};
/// @brief  used by the DataElement class
class DisableSerializability {};

/// @brief  is a container class which manages the creation and
///         access to a data element of type _DataType
    template< typename _DataType, bool _IsDataSerializable = std::is_base_of<Serializable,_DataType>::value >
    class DataElement :
        //  derive from SerializableElement, only if the template type _DataType is derived from the interface Serializable
        public
        std::conditional<
            _IsDataSerializable,
            SerializableElement,    // add additional properties to DataElement if its Serializable
            DisableSerializability >::type {
    public:
        DataElement(): m_content(new _DataType()){}

        void foo(int x) { std::cout << "in foo" << std::endl; }

        template <bool _EnabledAbility = _IsDataSerializable>
        void unloadTo(typename std::enable_if<_EnabledAbility, int>::type x)
        { std::cout << "in unloadTo" << std::endl; }

        template <bool _EnabledAbility = _IsDataSerializable>
        void loadFrom(typename std::enable_if<_EnabledAbility, int>::type x)
        { std::cout << "in loadFrom" << std::endl; }

    private:
        _DataType* m_content;
    };


    #endif /* TESTENABLEIF_H_ */

调用类DataElement的测试代码

main.cpp

#include "testEnableIF.h"

class SerializableType : public Serializable {
    int x;
    int y;
    int z;
};
class NonSerializableType {
    int u;
};

int main() {
    SerializableType sType;
    NonSerializableType nType;  // other type without being derived from Serializables

    DataElement<SerializableType> dataEle;
    dataEle.unloadTo(3);

    return 0;
}

共有1个答案

阎弘
2023-03-14
template <bool _EnabledAbility = _IsDataSerializable>
void unloadTo(typename std::enable_if<_EnabledAbility, int>::type x);

不是对

virtual void unloadTo(int x) = 0;

您甚至可以通过添加覆盖来获得错误。

修复的方法是从一个具体的类继承,该类继承自SerializableElement,而不是仅从接口继承。

演示

 类似资料:
  • Jinja 最为强大的地方在于他的模板继承功能,模板继承允许你创建一个基础的骨架模板, 这个模板包含您网站的通用元素,并且定义子模板可以重载的 blocks 。 听起来虽然复杂,但是其实非常初级。理解概念的最好方法就是通过例子。 基础模板 在这个叫做 layout.html 的模板中定义了一个简单的 HTML 文档骨架,你可以 将这个骨架用作一个简单的双栏页面。而子模板负责填充空白的 block:

  • 模板继承可以减少页面内容的重复定义,实现页面内容的重用 典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义 block标签:在父模板中预留区域,在子模板中填充 extends继承:继承,写在模板文件的第一行 定义父模板base.html { % block block_name % } 这里可以定义默认值 如果不定义默认值,则表示空字符串 { %

  • Jade 支持通过 block 和 extends 关键字来实现模板继承。 一个块就是一个Jade的"block" ,它将在子模板中实现,同时是支持递归的。 Jade 块如果没有内容,Jade会添加默认内容,下面的代码默认会输出block scripts, block content, 和 block foot. html head h1 My Site - #{title}

  • 继承 继承能够创建可复用的模板,定义页面的骨架,然后被子模板填充,子模板又可以作为父模板被继承。 继承主要通过两个标签语法实现 <t:template> 定义要继承的父模板 <b:block> 在父模板中用来定义可以被填充的区域;在子模板中用来定义将内容填充到父模板的指定区域 定义父模板 layout.vdt <div> <b:header> <div>父模板头部</div> </

  • 模板继承是 ThinkCMF推荐一种布局方式,它比上一篇讲的模板布局更灵活;模板继承就是你先定义一个基础的模板,在这个基础模板你可以设置很多个区块( block),然后在其它实际要渲染的子模板文件中用 extend标签继承这个基础模板,在子模板中定义name相同的 block,这样就可以对基础模板中定义的区块进行重载; 每个区块都是<block></block>这样的标签,如: <block na

  • 模板继承是 ThinkCMF推荐一种布局方式,它比上一篇讲的模板布局更灵活;模板继承就是你先定义一个基础的模板,在这个基础模板你可以设置很多个区块( block),然后在其它实际要渲染的子模板文件中用 extend标签继承这个基础模板,在子模板中定义name相同的 block,这样就可以对基础模板中定义的区块进行重载; 每个区块都是<block></block>这样的标签,如: <block na