我有一个模板定义的类来处理所有不同方法的处理。这些方法各不相同,或者可以根据执行的执行类型进行分组。所以我将继承超类处理属性,但定义了需要处理的所有不同方法。 我有函数指针不匹配错误。任何人都可以为这个问题提出解决方案
template <class T_ENUM>
class Injection
{
public:
Injection();
~Injection();
virtual void addAllCalls( void );
bool addCall( T_ENUM );
protected:
void* data; // drive of device under test
struct call_info {
T_ENUM call_ref;
string time_stamp;
};
// class specific function pointer defenition
// call_status_s is defined struct
typedef void (Injection::*funcType)(call_status_s*);
// map contains all calls initialized and ready to be processed
std::map<T_ENUM, funcType> func_call_map;
// here i process the function pointer based on the T_ENUM
bool processCall ( T_ENUM );
virtual void initCallMap( void );
// initialise the functions taken from child class and store here
};
class Type_Injection : public Injection<enum_defined_for_Type> {
public:
void addAllCalls( void );
private:
void initCallMap ( void );
// would initialise func_call_map with the functions pointer of TypeFunction1
// this is the function im going to save as pointers in the list defined in super class
void TypeFunction1 ( call_status_s* );
};
编译错误:
error: cannot convert ‘void (Type_Injection::*)(call_status_s*)’ to
‘void (Injection<enum_defined_for_Type>::*)(call_status_s*)’ in
assignment
再次抱歉无法添加完整的代码。
答案 0 :(得分:2)
这不是类型安全的,因为你有一个(隐藏的)协变参数。
实际函数Type_Injection::TypeFunction1
需要类型为this
的{{1}}参数。但是呼叫站点只提供Type_Injection
而不是后者的每个实例都是前者之一。
实际参数可能总是更多派生类型,在这种情况下,您可以使用强制转换来覆盖编译器类型检查。但我只会使用Injection<enum_defined_for_type>
,并在向地图添加回调时使用std::function<void (call_status_s*)>
来指定目标对象(假设目标对象始终是持有地图的类实例,并且不会改变在通话时间)。
std::bind
在您的特定情况下,另一个选项就是使您的typedef std::function<void (call_status_s*)> funcType;
// map contains all calls initialized and ready to be processed
std::map<T_ENUM, funcType> func_call_map;
void Type_Injection::initCallMap ( void ) override
{
using std::placeholders::_1;
func_call_map[T_ENUM_FUNCTION1] = std::bind(&Type_Injection::TypeFunction1, this, _1);
}
函数生成processCall
选择器T_ENUM
(不应该接受virtual
函数传递给被调用函数的参数?)。在派生类中,您可以使用call_status_s*
语句将switch
值映射到派生类中的函数。这是非常有效的,完全类型安全的,并且当值不匹配/未知时可以委托给基类,以允许在类层次结构的不同级别中实现不同的行为。与地图不同,这只允许查找,因此如果需要迭代,T_ENUM
的地图将是更好的选择。
另一个选项是“奇怪的重复模板模式”,它允许派生类通知基类对象的实际类型,以便映射可以包含std::function
函数指针。但这消除了在调用树的多个级别提供行为的能力。