通过覆盖类型转换动态调用函数

时间:2016-06-16 12:45:55

标签: c++ operator-overloading c++03

#include <iostream>

using namespace std;

class Base
{
public:
  void who()
  {
    cout << "I am " << _name << endl;
  }

protected:
  std::string _name;
};

class A : public Base
{
public:
  A()
  {
    _name = "A class";
  }
};

class B : public Base
{
public:
  B()
  {
    _name = "B class";
  }
};

class Wrapper
{
public:
  Wrapper(Base *i):_data(i)
  {
  }

  operator A()
  {
      A a;
  //  dynamic_cast<A*>(_data);
      return a;
  }

  operator B()
  {
      B a;
   // dynamic_cast<B*>(_data);
      return a;
  }
private:
  Base* _data;
};

void madeForClass(A iObject)
{
  cout << "call madeForClass A";
}

void madeForClass(B iObject)
{
  cout << "call madeForClass B";
}

int main()
{
  A a;
  Base* b = &a;

  madeForClass(Wrapper(b));

  return 0;
}

当我执行此操作时,我从编译中得到错误: e rror:调用重载'madeForClass(Wrapper)'是不明确的 据我所知,即使我超载了类型转换,也无法推断出正确的功能。但是,我怎样才能实现这种活力呢?

有关更多信息,我想以某种方式在重载函数或某处使用dynamic_cast,以便基于强制转换的结果,它应该选择相应的madeForClass函数。

对于给定的示例,转换将为'B'失败,因此应调用madeForClass(A i);

1 个答案:

答案 0 :(得分:1)

作为替代方案,您可以

class Wrapper
{
public:
    Wrapper(Base *i) : _data(i) {}

    template <typename F>
    auto Apply(F f)
    {
        if (auto a = dynamic_cast<A*>(_data)) {
            f(*a);
        } else if (auto b = dynamic_cast<B*>(_data)){
            f(*b);
        }
    }

private:
  Base* _data;
};

然后

Wrapper(base).Apply([](const auto& e){ madeForClass(e); });

Demo

或使用访问者而不是手动dynamic_cast