简体   繁体   English

哪个转换应与模板类参数dynamic_cast或reinterpet_cast一起使用?

[英]which cast should be used with a template class parameter, dynamic_cast or reinterpet_cast?

Could someone please help me? 有人可以帮我吗?

As far as I know, reinterpet_cast should be avoided at all cost, because it is dangerous. 据我所知,应该不惜一切代价避免reinterpet_cast,因为这很危险。 However in my current situation it is the only cast that is working. 但是在我目前的情况下,它是唯一起作用的演员。 Normally I would use dynamic_cast, because of inheritence, but the template class specialization does not let me to use dynamic_cast. 通常,由于继承原因,我将使用dynamic_cast,但是模板类专门化不允许我使用dynamic_cast。

In the current situation, my program looks like this. 在当前情况下,我的程序如下所示。

class Object {
public:
  virtual ~Object() = default;
};

template<typename SenderType, typename ...ArgumentType>
class EventCallback : public Object {
public:
  typedef void(SenderType::*Callback)(ArgumentType...);

  EventCallback(Callback callback, SenderType *sender)
    : m_callback{ callback }, m_sender{ sender } {
  }

  virtual ~EventCallback() = default;

  void operator()(ArgumentType ...args) {
    (m_sender->*m_callback)(args...);
  }
private:
  Callback m_callback;
  SenderType *m_sender;
};

template<typename SenderType, typename ...ArgumentType>
class Event : public Object {
public:
  virtual ~Event() = default;

  void operator+=(EventCallback<SenderType, ArgumentType...> callback) {
    m_callbacks.emplace_back(callback);
  }

  void operator()(ArgumentType ...args) {
    for (auto callback : m_callbacks) {
      callback(args...);
    }
  }

  private:
    std::vector<EventCallback<SenderType, ArgumentType...>> m_callbacks;
};    

class ApplicationView : public Object {
public:
  Event<Object> Activated;
  void Activate() {
    // activation logic ...
    Activated();
  }
};


class Application : public Object {
public:
  Application() {
    auto onViewActivated = EventCallback<Application>{&Application::OnViewActivated, this };
    m_view.Activated += reinterpret_cast<EventCallback<Object>&>(onViewActivated);
    m_view.Activate();
  }
  void OnViewActivated() {
  }
};

If I modify the above code to dynamic_cast, I get bad dynamic_cast exception. 如果将上面的代码修改为dynamic_cast,则会收到错误的dynamic_cast异常。 If I use reinterpet_cast, my code runs just fine. 如果我使用reinterpet_cast,则我的代码可以正常运行。

Any suggestions? 有什么建议么?

This is not an answer to the questions asked, so my apologies to Rajmund, and I realize that this "answer" will likely be downvoted because of it. 这不是对所提问题的答案,因此我对拉杰蒙德表示歉意,并且我意识到此“答案”可能会因此而被否决。

I'm trying to show how to get rid of having the common Object class, and avoid using casts altogether. 我正在尝试说明如何摆脱使用通用的Object类,并避免完全使用强制类型转换。 Too long to show in a comment, and code snippets do not format well in a comment anyway. 注释中显示的时间太长,并且代码片段在注释中的格式仍然不正确。

Should compile and run. 应该编译并运行。 I used C++17. 我用的是C ++ 17。 I added some placeholder code, which was assumed in Rajmund's code. 我添加了一些占位符代码,Rajmund的代码中假定了这些代码。 I added cout to show what is happening. 我添加了cout以显示正在发生的事情。

I do not normally write templates, so I'm expected that the template code could be made nicer. 我通常不编写模板,因此我希望可以使模板代码更好。 In particular, it could be nice if the dependent code could do Event<void()> instead of Event<function<void()>> ... I'll leave that as an exercise for the reader. 特别是,如果从属代码可以执行Event<void()>而不是Event<function<void()>>话,那将是一个不错的选择……我将其留给读者练习。

#include <functional>
#include <vector>
#include <iostream>

using std::function;
using std::vector;
using std::cout;
using std::endl;

template<typename F>
class Event
{
public:
  void operator+=(F callback)
  {
    m_callbacks.emplace_back(callback);
  }

  template <typename ...ArgumentTypes>
  void operator()(ArgumentTypes ...args)
  {
    // Need a copy, in case a callback adds more callbacks, or removes itself.
    // (I assume callbacks removing themselves, like C#, will be added.)
    auto temp_callbacks = m_callbacks;
    cout << "Event callback list has " << m_callbacks.size() << endl;
    for (auto callback : temp_callbacks)
    {
      cout << "Calling Event callback..." << endl;
      callback(args...);
    }
  }

private:
  vector<F> m_callbacks;
};

class ApplicationView final
{
public:
  Event<function<void()>> Activated;
  void Activate()
  {
    cout << "ApplicationView::Activate has just been called." << endl;
    Activated();
  }
};

class ApplicationViewProvider final
{
public:
  static ApplicationView CreateView();
};

ApplicationView ApplicationViewProvider::CreateView()
{
  return ApplicationView{};
}

class Application final
{
  friend int main();
  ApplicationView m_view;
public:
  Application() :
    m_view{ ApplicationViewProvider::CreateView() }
  {
    auto onViewActivated = [this]() { this->OnViewActivated(); };
    m_view.Activated += onViewActivated;
    m_view.Activate();
  }

  void OnViewActivated()
  {
    cout << "HURRAY! Application::OnViewActivated has been notified." << endl;
  }
};

int main()
{
  cout << "Making Application\n + hooks up OnViewActivated callback\n + calls view's Activate" << endl;
  Application application;
  cout << "\nCalling the view's Activate again, in main" << endl;
  application.m_view.Activate();
}

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

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