简体   繁体   English

C ++验证模板类型

[英]C++ Verify template type

Sorry for my poor english I'll try to do my best. 对不起,我的英语很差,我会努力做到最好。

I want to design an interface that should be used like this: 我想设计一个应该像这样使用的接口:

class MyObject : public IMyInterface<MyObject>
{
    // ...
};

The interface could look like this: 界面可能如下所示:

template <class _TMyObject>
class IMyInterface
{
    virtual _TMyObject* Get() = 0;
};

What i'm looking after, is a way to verify, at compile time, that the interface is used as intended. 我正在寻找的是一种在编译时验证接口是否按预期使用的方法。 How can I test if _TMyObject "is-a" IMyInterface<_TMyObject> ? 如何测试_TMyObject “是否是一个” IMyInterface<_TMyObject> Inside the interface definition, with a static_assert for example. 在接口定义中,例如使用static_assert。

Thanks for any help :). 谢谢你的帮助 :)。 Have a nice day! 祝你今天愉快!

You can't put static_assert inside the class itself, because D is an incomplete type, but you can put it in the destructor (or constructor, but there can be many constructors): 你不能把static_assert放在类本身,因为D是一个不完整的类型,但你可以将它放在析构函数(或构造函数中,但可以有许多构造函数):

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
}

Addition. 加成。 Note that this solution is not a complete protection against incorrect usage of CRTP. 请注意,此解决方案不能完全防止错误使用CRTP。 Please refer to Some Programmer Dude 's answer for a nice example of error that can't be caught by it. 请参考一些程序员Dude的答案, 找出一个不能被它捕获的错误示例。

Since C++11 there are many type property traits that could be used to do checks at compile-time. 从C ++ 11开始,有许多类型的属性特性可用于在编译时进行检查。

For example std::is_base_of which in your case could be used like perhaps 例如std::is_base_of在你的情况下可以像或许一样使用

template<typename TChild>
struct IMyInterface
{
    static_assert(std::is_base_of<IMyInterface, TChild>::value, "Derived class not derived from IMyInterface");

    // ...
};

Note: The exact code shown above will not work directly, but rather show the principle. 注意:上面显示的确切代码不会直接起作用,而是显示原理。

Of course, that do allow something like 当然,这确实允许类似的东西

class MyFirstClass : public IMyInterface<MyFirstClass>
{
    // ...
};

//                        Note wrong class in template
//                                        vvvvvvvvvvvv
class MySecondClass : public IMyInterface<MyFirstClass>
{
    // ...
};

So to answer your question if it's possible for such a check: Not really the way you want. 所以,如果有可能进行这样的检查,请回答你的问题:不是你想要的方式。 Even using other traits and meta-programming, you can never guarantee that the template argument for the interface class is "correct" when used in the CRTP . 即使使用其他特征和元编程,也无法保证在CRTP中使用时接口类的模板参数是“正确的”。

The only way I can see it work is by using down-casting at run-time with dynamic_cast , something like dynamic_cast<TChild*>(this) != nullptr in the interface class. 我能看到它工作的唯一方法是在运行时使用dynamic_cast进行向下转换,类似于接口类中的dynamic_cast<TChild*>(this) != nullptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM