如何根据模板类型启用继承开关
How to enable a inheritance switch depending on a template type
我想根据传递给 class:
的模板参数实现一个实现开关
- 如果传递的模板类型派生自特定的class(此处:
Serializable) 然后创建一个容器 DataElement
该类型的实例应派生自 SerializableElement 和
重载从它继承的两个纯虚方法(这里:
unloadTo 和 loadFrom).
- 然而,如果传递的模板类型不是从 Serializable 派生的
DataElement 不应派生自 SerializableElement,因此
不应重载纯虚方法。
我调整了我的代码,以便能够通过此处提到的技巧隐藏 class DataElement 中的 class 方法
不过,在针对我的问题调整技巧时,我确实遇到了以下错误:
error: cannot declare variable ‘dataEle’ to be of abstract type
‘DataElement’
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_ */
调用 class 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;
}
template <bool _EnabledAbility = _IsDataSerializable>
void unloadTo(typename std::enable_if<_EnabledAbility, int>::type x);
不是
的覆盖
virtual void unloadTo(int x) = 0;
你甚至会通过添加 override
.
来得到错误
解决方法是继承自 SerializableElement
的具体 class 而不是仅继承接口。
我想根据传递给 class:
的模板参数实现一个实现开关- 如果传递的模板类型派生自特定的class(此处: Serializable) 然后创建一个容器 DataElement 该类型的实例应派生自 SerializableElement 和 重载从它继承的两个纯虚方法(这里: unloadTo 和 loadFrom).
- 然而,如果传递的模板类型不是从 Serializable 派生的 DataElement 不应派生自 SerializableElement,因此 不应重载纯虚方法。
我调整了我的代码,以便能够通过此处提到的技巧隐藏 class DataElement 中的 class 方法
不过,在针对我的问题调整技巧时,我确实遇到了以下错误:
error: cannot declare variable ‘dataEle’ to be of abstract type ‘DataElement’
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_ */
调用 class 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;
}
template <bool _EnabledAbility = _IsDataSerializable>
void unloadTo(typename std::enable_if<_EnabledAbility, int>::type x);
不是
的覆盖virtual void unloadTo(int x) = 0;
你甚至会通过添加 override
.
解决方法是继承自 SerializableElement
的具体 class 而不是仅继承接口。