Variadic 模板回调接口 class 实例化不能重载
Variadic template callback interface class instanciation cannot be overloaded
我想做的是有一个只有函数成员的回调接口。
今天,我有 2 个最终 classes,它们使用此接口通过在 CallbackStore 中保存特定回调来定义它们的行为。
根据我的约束 (),我实现的是以下最小编译代码,但只有一个 child class:
#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.
}
通过添加新的 child class,
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() {};
^~~~~~~~~
而不是专门化模板
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 );
};
};
我想问题出在这对构造函数上
Interface() : Base() {};
Interface(ArgT... arg) : Base(arg...) {};
当ArgT...
为空列表时,它们是同一个构造函数并发生冲突。
我向SFINAEenable/disable建议第二个如下
template <bool B = (sizeof...(ArgT)>0u), std::enable_if_t<B, bool> = true>
Interface(ArgT... arg) : Base(arg...) {};
这样,仅当 ArgsT...
不为空时才启用第二个构造。
另一种方法是避免 SFINAE(启用的第二个构造函数),但将其转换为模板,使用可变参数 un-named 未使用模板参数列表,因此第一个具有优先级
Interface() : Base() {};
template <typename ...>
Interface(ArgT... arg) : Base(arg...) {};
我想做的是有一个只有函数成员的回调接口。 今天,我有 2 个最终 classes,它们使用此接口通过在 CallbackStore 中保存特定回调来定义它们的行为。
根据我的约束 (
#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.
}
通过添加新的 child class,
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() {};
^~~~~~~~~
而不是专门化模板
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 );
};
};
我想问题出在这对构造函数上
Interface() : Base() {};
Interface(ArgT... arg) : Base(arg...) {};
当ArgT...
为空列表时,它们是同一个构造函数并发生冲突。
我向SFINAEenable/disable建议第二个如下
template <bool B = (sizeof...(ArgT)>0u), std::enable_if_t<B, bool> = true>
Interface(ArgT... arg) : Base(arg...) {};
这样,仅当 ArgsT...
不为空时才启用第二个构造。
另一种方法是避免 SFINAE(启用的第二个构造函数),但将其转换为模板,使用可变参数 un-named 未使用模板参数列表,因此第一个具有优先级
Interface() : Base() {};
template <typename ...>
Interface(ArgT... arg) : Base(arg...) {};