对不起,我的英语不好,我会尽力而为。
我想设计一个应该像这样使用的接口:
class MyObject : public IMyInterface<MyObject>
{
// ...
};
界面可能如下所示:
template <class _TMyObject>
class IMyInterface
{
virtual _TMyObject* Get() = 0;
};
我要照顾的是一种在编译时验证接口是否按预期使用的方法。
如何测试_TMyObject
是否为IMyInterface<_TMyObject>
?在接口定义内部,例如带有static_assert的
感谢您的帮助:)。 祝你有美好的一天!
答案 0 :(得分:6)
您不能将static_assert
放在类本身内,因为D
是不完整的类型,但是您可以将其放在析构函数(或构造函数,但可以有很多构造函数)中:< / p>
template<class D>
struct B
{
~B()
{
static_assert(std::is_base_of_v<B, D>);
};
};
struct Not_E {};
struct D : B<D> { };
struct E : B<Not_E> { };
void foo()
{
D d; // OK
E e; // Fails
}
添加。。请注意,此解决方案并不是防止CRTP错误使用的完整保护措施。请参考 Some Programmer Dude 的答案,以获取无法捕获的错误示例。
答案 1 :(得分:2)
自C ++ 11起,many type property traits可用于在编译时进行检查。
例如std::is_base_of
,在您的情况下,它可能会被使用
localhost/my_site_folder/public/images/example.png?d41d8cd98f00b204e9800998ecf8427e
注意:上面显示的确切代码不能直接使用,而是可以显示原理。
当然,确实允许类似
template<typename TChild>
struct IMyInterface
{
static_assert(std::is_base_of<IMyInterface, TChild>::value, "Derived class not derived from IMyInterface");
// ...
};
因此,如果可以进行此类检查,请回答您的问题:不是您想要的方式。即使使用其他特征和元编程,也不能保证在CRTP中使用时,接口类的模板参数是“正确的”。
我唯一能看到它工作的方法是在运行时使用class MyFirstClass : public IMyInterface<MyFirstClass>
{
// ...
};
// Note wrong class in template
// vvvvvvvvvvvv
class MySecondClass : public IMyInterface<MyFirstClass>
{
// ...
};
进行向下广播,类似于接口类中的dynamic_cast
。