RSS

Tag Archives: C++11

Nicer type switch with C++11 lambdas.

Yeah, I know we are not suppose to do type switches. And yeah, we still do. This is how I do it now thanks to C++11 lambdas:

void onEvent(const Event& e) override
{
  tswich(e)
    .on<TouchEvent>([] (const TouchEvent& e)
    {
      LOG_INFO << "Touch " << e.finger() << " at " << e.x() << " down";
    })
    .on<MouseEvent>([](const MouseEvent& e)
    {
      LOG_INFO << "Mouse at " << e.x() << "," << e.y();
    }).
    onDynamic<KeyEvent>()[const KeyEvent& e)
    {
      LOG_INFO << "Key press " << e.code();
    });
}

C++14 ‘s lambdas will make this even nicer as there will be no need to spell destination type twice (in on<> and lambda param). on() is strict and on enters only exact type (checked via typeid). onDynamic() on the other hand is less restrictive and will allow any type that is dynamically castable to destination type.

To make it work all that is needed are those few lines:

template <class Src>
class TypeSwitch
{
public:

  TypeSwitch(const Src& src) : src_(src) {}

  template <class Dst, class F>
  TypeSwitch on(F f)
  {
    if (typeid(src_) == typeid(Dst))
    {
      f(static_cast<const Dst&>(src_));
    }
    return TypeSwitch(src_);
  }

  template <class Dst, class F>
  TypeSwitch onDynamic(F f)
  {
    if (auto ptr = dynamic_cast<const Dst*>(&src_))
    {
      f(*ptr);
    }
    return TypeSwitch(src_);
  }

private:
 const Src& src_;
};

template <class Src>
TypeSwitch<Src> tswich(const Src& v)
{
 return TypeSwitch<Src>(v);
}
 
Leave a comment

Posted by on September 17, 2013 in Uncategorized

 

Tags: ,