【发布时间】:2018-09-06 15:32:49
【问题描述】:
问题
我想检测一个类是否有成员变量,如果有,则使静态断言失败。比如:
struct b {
int a;
}
static_assert(!has_member_variables<b>, "Class should not contain members"). // Error.
struct c {
virtual void a() {}
void other() {}
}
static_assert(!has_member_variables<c>, "Class should not contain members"). // Fine.
struct d : c {
}
static_assert(!has_member_variables<d>, "Class should not contain members"). // Fine.
struct e : b {
}
static_assert(!has_member_variables<e>, "Class should not contain members"). // Error.
struct f : c {
char z;
}
static_assert(!has_member_variables<f>, "Class should not contain members"). // Error.
有没有办法通过 SFINAE 模板实现这一点?这个类可能有继承,甚至可以使用虚函数进行多重继承(但基类中没有成员)。
动机
我有一个非常简单的设置如下:
class iFuncRtn {
virtual Status runFunc(Data &data) = 0;
};
template <TRoutine, TSpecialDataType>
class FuncRoutineDataHelper : public iFuncRtn {
Status runFunc(Data &data) {
static_assert(!has_member_variables<TRoutine>, "Routines shouldnt have data members!");
// Prepare special data for routine
TSpecialDataType sData(data);
runFuncImpl(sData);
}
class SpecificRtn :
public FuncRoutineDataHelper<SpecificRtn, MySpecialData> {
virtual Status runFuncImpl(MySpecialData &sData) {
// Calculate based on input
sData.setValue(someCalculation);
}
};
FunctionalityRoutines 是按每个滴答来管理和运行的。它们是定制的,可以执行各种各样的任务,例如联系其他设备等。传入的数据可以由例程操作,并保证在每次滴答执行时传入,直到功能完成。基于DataHelper 类传入正确的数据类型。我不想阻止未来的人们错误地将数据添加到功能例程中,因为这不太可能达到他们的预期。为了强制执行此操作,我希望找到一种使用静态断言的方法。
【问题讨论】:
-
那么如果一个基类有数据成员而不是派生类,没关系?
-
如果基类也应该为空,您可以使用
std::is_empty。否则,目前的C++没有办法。 -
@Rakete1111 任何继承树都不应该有成员变量。
-
@Brian
std::is_empty会检测到我的虚拟会员,所以我不能使用它。动机部分应该已经说明了这一点。 -
@dgnuff std::function 可以轻松打包状态(无数据类也可以,但前提是你有点淘气)。