简体   繁体   English

通过继承和模板进行static_pointer_cast

[英]static_pointer_cast through inheritance and template

I am having trouble finding a fix for the following error, thrown when compiling a std::static_pointer_cast<>() : 我在寻找以下错误时遇到了麻烦,这些错误是在编译std::static_pointer_cast<>()时抛出的:

error: invalid static_cast from type ecse::EventSubscriptionManager<ecse::BaseEvent>* to type ecse::EventSubscriptionManager<TestEvent>*

I have the following hierarchy. 我有以下层次结构。 In the end they will be filled with POD type members and will most likely become structs. 最后,它们将充满POD类型的成员,并且很可能成为结构。

class BaseEvent {};

template <class E>
class Event : public BaseEvent, public Type<E> {};

class TestEvent : public Event<TestEvent> {};

I am currently working on the Subscribe function part of the EventManager, however when compiling I am receiving the error posted above. 我目前正在使用EventManager的Subscribe函数,但是在编译时我收到了上面发布的错误。 Note: E::ID() is defined in the class as Type and is used for identifying the class type. 注意: E::ID()在类中定义为Type,用于标识类类型。

template <class E>
class EventSubscriptionManager
{
public:
  void Subscribe(std::function<void(E)>  fptr);
private:
  std::function<void(E)> event_function_;
};

class EventManager
{
public:
  template <class E>
  void Subscribe(std::function<void(E)> fptr)
  {
     std::shared_ptr<EventSubscriptionManager<E>> sub_manager_ptr;
     auto sub_manager_iterator = sub_managers_.find(E::ID());
     if(sub_manager_iterator == sub_managers_.end())
     {
       sub_manager_ptr = std::make_shared<EventSubscriptionManager<E>>();
     }
     else
     {
       sub_manager_ptr = std::static_pointer_cast<EventSubscriptionManager<E>>(sub_manager_iterator->second);
     }
     // Continue function...
  }
private:
  std::unordered_map<std::size_t, std::shared_ptr<EventSubscriptionManager<BaseEvent>>> sub_managers_;
}

I believe that the issue is that between the TestEvent and the BaseEvent there is the Event<E> class with the template, with TestEvent inheriting Event<TestEvent> instead of BaseEvent . 我认为问题在于,在TestEventBaseEvent存在带有模板的Event<E>类,其中TestEvent继承了Event<TestEvent>而不是BaseEvent Is this true? 这是真的? If so, how can I set up my hierarchy to allow for this type of casting? 如果是这样,我如何设置层次结构以允许这种类型的转换?

If that is not the case, what is the issue with the above static cast? 如果不是这种情况,那么上面的静态转换有什么问题?

In C++, there is no covariance or contravariance, there is no relationship between T<Base> and T<Sub> , even if there is one between Base and Sub . 在C ++中,即使在BaseSub之间不存在协方差或对立关系, T<Base>T<Sub>之间也没有关系。

You either need to build a common ancestor of different EventSubscriptionManager instances (eg: EventSubscriptionManagerBase ), and use that, or provide a converting constructor. 您要么需要构建不同EventSubscriptionManager实例的公共祖先(例如: EventSubscriptionManagerBase ),然后使用它,要么提供转换构造函数。

I can tell you why it does not compile. 我可以告诉你为什么它不能编译。 This is because 这是因为

EventSubscriptionManager<E>

is unrelated to 与...无关

EventSubscriptionManager<BaseEvent>

So, according to point 1.) on the reference page, 因此,根据参考页上的第1.)点

static_cast<EventSubscriptionManager<E>*>((EventSubscriptionManager<BaseEvent>*)nullptr)

is ill-formed. 格式不正确。

However, without knowing the background I can't tell what to do as a workaround. 但是,在不了解背景的情况下,我无法说出解决方法。 Just: you have to relate the two classes, or choose a completely new design. 公正:您必须将两个类联系起来,或者选择一个全新的设计。



In order to do so, here is a minimal example why it fails which might be helpful: 为此, 是一个失败的最小示例,这可能会有所帮助:

struct Base {};
struct Derived : Base {};

template<typename T>
struct Foo {};

int main()
{
   static_cast<Foo<Derived>*>((Foo<Base>*)nullptr);
}

You can try to improve on that. 您可以尝试对此进行改进。

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

相关问题 static_cast() 有效但 static_pointer_cast() 无效? - static_cast() works but static_pointer_cast() does not? unique_ptr的static_pointer_cast替代方案 - Alternatives of static_pointer_cast for unique_ptr static_pointer_cast是否更新引用计数 - Does static_pointer_cast update reference counting std :: move into static_pointer_cast:为什么static_pointer_cast没有rvalue引用重载? - std::move into static_pointer_cast: Why doesn't static_pointer_cast have an rvalue reference overload? 使用派生实例调用模板基类的友元函数时,如何避免使用“std::static_pointer_cast” - How to avoid having to use “std::static_pointer_cast” when calling a friend function of a template base class with a derived instance std :: static_pointer_cast vs static_cast <std :: shared_ptr <A >> - std::static_pointer_cast vs static_cast<std::shared_ptr<A>> std :: static_pointer_cast是否有任何额外的运行时开销? - Does std::static_pointer_cast have any additional runtime overhead? 为什么 `static_pointer_cast` 不能与 ADL 一起使用,但需要显式的 `std::`? - Why doesn't `static_pointer_cast` work with ADL, but requires explicit `std::`? 通过包含模板的继承链进行static_cast编译失败 - static_cast through inheritance chain that includes a template will fail to compile 存储 std::weak_ptr<void> 并使用 static_pointer_cast - Storing of std::weak_ptr<void> and using static_pointer_cast
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM