Problem
我想检测一个类是否有成员变量,如果有,则静态断言失败。就像是:
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);
}
};
The FunctionalityRoutine
是按每个刻度进行管理和运行的。它们是定制的,可以执行各种任务,例如联系其他设备等。传入的数据可以由例程操作,并保证在每次滴答执行时传入,直到功能完成。根据正确的数据类型传入DataHelper
班级。我不想阻止未来的人们错误地将数据添加到功能例程中,因为它不太可能达到他们的预期。为了强制执行此操作,我希望找到一种使用静态断言的方法。
您可以通过依赖编译器执行空基类优化来解决此问题,方法是检查是否派生自您的类T
与具有虚函数的空类具有相同的大小:
template<typename T, typename... BaseClasses>
class IsEmpty
{
// sanity check; see the updated demo below
static_assert(IsDerivedFrom<T, BaseClasses...>::value);
struct NonDerived : BaseClasses... { virtual ~NonDerived() = default; };
struct Derived : T { virtual ~Derived() = default; };
public:
inline static constexpr bool value = (sizeof(NonDerived) == sizeof(Derived));
};
这应该适用于单继承和多重继承。但是,当使用多重继承时,有必要列出所有基类,如下所示:
static_assert(IsEmpty<Derived, Base1, Base2, Base3>::value);
显然,这个解决方案排除了final
类。
这是更新的演示。 https://godbolt.org/z/-cvgaO
Here's the original demo. https://godbolt.org/z/Hbyd0O (doesn't work with multiple inheritance)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)