【问题标题】:How to enable a inheritance switch depending on a template type如何根据模板类型启用继承开关
【发布时间】:2017-05-05 10:07:52
【问题描述】:

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

  • 如果传递的模板类型派生自特定类(此处: Serializable) 然后是创建一个 该类型的实例应派生自 SerializableElement 和 重载从它继承的两个纯虚方法(这里: unloadTo 和 loadFrom)。
  • 然而,如果传递的模板类型不是从 Serializable 派生的 DataElement 不应该从 SerializableElement 派生,因此 不应重载纯虚方法。

我修改了我的代码,以便能够隐藏类 DataElement 中的类方法,通过这里提到的技巧 C++: Enable method based on boolean template parameter

虽然我确实遇到了以下错误,但在根据我的问题调整技巧时:

错误:不能将变量“dataEle”声明为抽象类型 ‘数据元素’


testEnableIF.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类的测试代码

ma​​in.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;
}

【问题讨论】:

    标签: c++ templates inheritance typetraits enable-if


    【解决方案1】:
    template <bool _EnabledAbility = _IsDataSerializable>
    void unloadTo(typename std::enable_if<_EnabledAbility, int>::type x);
    

    不是覆盖

    virtual void unloadTo(int x) = 0;
    

    您甚至可以通过添加 override 来得到错误。

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

    Demo

    【讨论】:

    • 不错的解决方案。您在 SerializableElement 上使用的 CRTP 模式是否意味着仍然可以访问 DataElement 的私有成员?什么是私有的:T& AsT() { return static_cast(*this); } 为?
    • 是的,它允许访问DataElement 的成员(但不能访问private 的成员,仅限protectedpublic)。
    猜你喜欢
    • 1970-01-01
    • 2020-06-26
    • 2018-05-23
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多