我要做的是仅具有一个函数成员的回调接口。 今天,我有2个最终类,它们使用此接口通过将特定的回调保存在CallbackStore中来定义其行为。
通过约束(here),我实现了以下最小限度的编译代码,但仅使用一个子类:
#include <iostream>
#include <stdint.h>
using namespace std;
static constexpr int STORE_SIZE = 4;
void* operator new(size_t size)
{
cout << "ERROR HEAP USED" << endl;
}
template<typename T, size_t storeSize>
class CallbackStore
{
public:
CallbackStore() : that_(nullptr) {};
CallbackStore(T* that) : that_(that) {};
using CallbackCondition = bool (*) (T*);
using CallbackAction = void (*) (T*,int);
struct Step
{
CallbackCondition pCallbackCondition;
CallbackAction pCallbackAction;
};
void setStep(int stepId,CallbackCondition pCallbackCondition, CallbackAction pCallbackAction)
{
if(stepId<storeSize)
{
store[stepId].pCallbackCondition = pCallbackCondition;
store[stepId].pCallbackAction = pCallbackAction;
}
else
{
cout << "pointer error" << endl;
}
}
void callStep(int stepId, int param)
{
if((stepId<storeSize) &&
(store[stepId].pCallbackCondition != nullptr) &&
(store[stepId].pCallbackAction != nullptr) &&
(that_ != nullptr))
{
bool isActive = (*(store[stepId].pCallbackCondition))(that_);
if(isActive) {(*(store[stepId].pCallbackAction))(that_,param);}
}
else
{
cout << "pointer error" << endl;
}
}
Step store[storeSize];
T* that_;
};
template<typename Base, typename... ArgT>
class Interface : public Base // interface
{
public:
Interface() : Base() {};
Interface(ArgT... arg) : Base(arg...) {};
public:
static bool True(Base* baseInstance)
{
return true;
}
static bool IsNegative(Base* baseInstance)
{
return ((static_cast<Base*>(baseInstance))->getValue() < 0);
}
static bool IsNull(Base* baseInstance)
{
return ((static_cast<Base*>(baseInstance))->getValue() == 0);
}
static bool IsPositive(Base* baseInstance)
{
return (IsNegative(baseInstance) == false);
}
static void PrintValue(Base* baseInstance, int value)
{
cout << "print this value : " << value << "." << endl;
}
};
template<typename Base>
class Interface<Base,void>// interface
{
public:
Interface() : Interface<Base,void>() {};
};
class MotherA
{
public:
MotherA(){};
MotherA(int x): x_(x){};
int getValue() { return x_; }
void setValue(int x) { x_ = x; }
protected:
int x_ = -3;
};
class ListModel : public MotherA
{
};
class FinalLChild : public Interface<ListModel>, public CallbackStore<ListModel, STORE_SIZE>
{
public:
FinalLChild(): Interface(), CallbackStore(this)
{
setStep(0, &Interface::IsNegative, &Interface::PrintValue );
setStep(1, &Interface::IsNegative, &Interface::PrintValue );
setStep(2, &Interface::IsNull, &Interface::PrintValue );
setStep(3, &Interface::True, &Interface::PrintValue );
};
};
class ValueModel : public MotherA
{
public:
ValueModel() : MotherA(), y_(0) {};
ValueModel(int x,int y) : MotherA(x), y_(y) {};
void reset(){x_= y_;};
int y_ = 0;
};
class ValueChild : public Interface<ValueModel,int,int>, public CallbackStore<ValueModel, STORE_SIZE>
{
public:
ValueChild() : Interface(), CallbackStore(nullptr){};
ValueChild(int x,int y): Interface(x,y), CallbackStore(this){};
};
class FinalVChild : public ValueChild
{
public:
FinalVChild():ValueChild(2,0)
{
setStep(0, &Interface::IsPositive, &Interface::PrintValue );
setStep(1, &Interface::IsPositive, &Interface::PrintValue );
setStep(2, &Interface::IsNull, &Interface::PrintValue );
setStep(3, &Interface::IsNull, &Interface::PrintValue );
};
};
int main()
{
FinalVChild c;
for(int i = 0; i < STORE_SIZE; i++)
{
c.callStep(i,8);
}
cout << "reset:\n";
c.reset();
for(int i = 0; i < STORE_SIZE; i++)
{
c.callStep(i,8);
}
// shall print "print this value : 8." 3 times if x_ is null, twice if x_ is negative.
}
通过添加新的子类,
class ListModel : public MotherA
{
};
class FinalLChild : public Interface<ListModel>, public CallbackStore<ListModel, STORE_SIZE>
{
public:
FinalLChild(): Interface(), CallbackStore(this)
{
setStep(0, &Interface::IsNegative, &Interface::PrintValue );
setStep(1, &Interface::IsNegative, &Interface::PrintValue );
setStep(2, &Interface::IsNull, &Interface::PrintValue );
setStep(3, &Interface::True, &Interface::PrintValue );
};
};
和main()
FinalLChild d;
cout << "d:\n";
for(int i = 0; i < STORE_SIZE; i++)
{
d.callStep(i,8);
}
这将引发以下编译错误:
main.cpp: In instantiation of ‘class Interface<ListModel>’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',113)">main.cpp:113:57</span>: required from here
main.cpp:65:5: error: ‘Interface::Interface(ArgT ...) [with Base = ListModel; ArgT = {}]’ cannot be overloaded
Interface(ArgT... arg) : Base(arg...) {};
^~~~~~~~~
main.cpp:64:5: error: with ‘Interface::Interface() [with Base = ListModel; ArgT = {}]’
Interface() : Base() {};
^~~~~~~~~
答案 0 :(得分:1)
我想问题是这两个构造函数
Interface() : Base() {};
Interface(ArgT... arg) : Base(arg...) {};
当ArgT...
为空列表时,它们是相同的构造函数并且发生冲突。
我建议SFINAE启用/禁用第二个功能,如下所示
template <bool B = (sizeof...(ArgT)>0u), std::enable_if_t<B, bool> = true>
Interface(ArgT... arg) : Base(arg...) {};
这样,仅当ArgsT...
不为空时才启用第二个构造。
一种替代方法是避免SFINAE(有史以来启用的第二个构造函数),但将其转换为一个模板,并带有未使用的模板参数的可变参数未命名列表,因此第一个具有优先级
Interface() : Base() {};
template <typename ...>
Interface(ArgT... arg) : Base(arg...) {};
答案 1 :(得分:0)
代替专用模板
template<typename Base>
class Interface<Base,void>// interface
{
public:
Interface() : Interface<Base,void>() {};
};
class ListModel : public MotherA
{
};
class FinalLChild : public Interface<ListModel>, public CallbackStore<ListModel, STORE_SIZE>
{
public:
FinalLChild(): Interface(), CallbackStore(this)
{
setStep(0, &Interface::IsNegative, &Interface::PrintValue );
setStep(1, &Interface::IsNegative, &Interface::PrintValue );
setStep(2, &Interface::IsNull, &Interface::PrintValue );
setStep(3, &Interface::True, &Interface::PrintValue );
};
};
使用class NoneT {};
class NoneT {};
class ListModel : public MotherA
{
};
class FinalLChild : public Interface<ListModel,NoneT>, public CallbackStore<ListModel, STORE_SIZE>
{
public:
FinalLChild(): Interface(), CallbackStore(this)
{
setStep(0, &Interface::IsNegative, &Interface::PrintValue );
setStep(1, &Interface::IsNegative, &Interface::PrintValue );
setStep(2, &Interface::IsNull, &Interface::PrintValue );
setStep(3, &Interface::True, &Interface::PrintValue );
};
};