【问题标题】:Curiously Recurring Template Pattern Illegal call of non-static member funciton奇怪地重复出现的模板模式非法调用非静态成员函数
【发布时间】:2018-02-23 10:25:06
【问题描述】:

我最近尝试了很多模板元编程,尤其是使用 CRTP,但遇到了名义上的错误。具体错误 C2352 'MeshComponent::InternalSetEntity': 非法调用非静态成员函数。

我的代码的最小、完整和可验证的片段如下:

组件.h

class Entity //Forward declaration

template<class T, EventType... events>
class Component {
private:
    short entityID;
public:
    void SetEntity(Entity& _entity) { entityID = _entity.GetId(); T::InternalSetEntity(_entity); }
protected:  
    void InternalSetEntity(Entity& _entity) {}
};

MeshComponent.h

#include "Component.h"
class MeshComponent : public Component<MeshComponent> {
    friend class Component<MeshComponent>;
protected:
    void InternalSetEntity(Entity& _entity);
};

MeshComponent.cpp

#include "MeshComponent.h"
void MeshComponent::InternalSetEntity(Entity& _entity) {
    //Nothing yet
}

Entity.h

class Entity {
private:
    short id;
public:
    short GetId() {return id;}
};

我没有声明任何静态函数,也不想声明。事实上,我要求这些是成员函数,因为它们将对实例特定的数据进行操作。

如果有人知道为什么会发生此错误以及问题的可能解决方案,我将不胜感激。提前致谢。

【问题讨论】:

    标签: c++ templates static c++14 crtp


    【解决方案1】:

    您知道并确保MeshComponent 继承自Component&lt;MeshComponent&gt;,但编译器不知道:据其在Component 的定义中所知,Component&lt;T&gt;T 是不相关的。您需要明确执行向下转型:

    static_cast<T*>(this)->InternalSetEntity(_entity);
    

    【讨论】:

    • 哇,我从来没有想过这一点,但这完全可以解释为什么它抱怨非静态函数。所以要完成 CRTP,我们需要明确告诉它使用自己的实例。在使用模板时必须指出对我们来说似乎很明显的东西,这有一些奇怪的美妙之处。为了确保最后一部分正确,我们必须将其向下转换为指针,因为“this”是一个指针。但是“this”看起来是一个 const 指针,所以我们可以将它向下转换为一个引用吗?
    • @Ryoku 它是const 与此无关,您确实可以做到static_cast&lt;T&amp;&gt;(*this)。我通常将其分解为一对(const 和非const)成员函数。
    • 太棒了。如果我想通过在最后添加孩子的方法来扩展父构造方法怎么办?有点像Component(short id) { entityID = id; T(id) } 这样就足够了,还是我不得不再次对T 失望?
    • @Ryoku 不,那没有办法工作。但是你不需要它,因为派生的构造函数在做任何其他事情之前已经调用了基础构造函数。请注意,您不能在构造函数(或析构函数)中向下转换,因为派生对象还不存在(或不再存在)。
    • 好吧,无论如何都会调用基础构造函数,我不认为它会因为基础是模板,很高兴知道。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    相关资源
    最近更新 更多