C++多方法和编译时检测

C++ multimethods and compile time detection

本文关键字:检测 编译 方法 C++      更新时间:2023-10-16

我有以下代码:

class A{};
class B: public A{};
class C: public A{};
class MyVisitor
{
   public:
       void visit(B*);
       void visit(C*);
};

然后收集A*对象,我想实现如下:

1)

MyVisitor visitor;
for(vector<A*>::iterator it = vec.begin(); it!= vec.end();it++)
     visitor->visit(a);

2) 以某种方式在编译时确定A*是否指向派生对象D,并给出编译器错误,如果MyVisitor::visit(D*)函数不存在

我知道1)可以通过一些多方法实现,我想我可以找到一些c++的多方法实现。但有可能吗?

您可以像这样使用dynamic_cast(在for循环的主体中),因为行为在运行时应该有所不同(根据实际数据类型)。

   ClassB* ba = dynamic_cast<ClassB*>(a);
   if (ba)
      visitor->visit(ba);
   ClassC* ca = dynamic_cast<ClassC*>(a);
   if (ca)
      visitor->visit(ca);

也许您的visit函数可能被声明为virtual(用于ClassD)。

否则,将您的类组织为类的树(而不是林),并拥有最顶端的根类

  class Topmost {
     virtual int classnum() const;

并采用约定,即每个非抽象类都给出其唯一的classnum等。或者具有元类机制(例如Qt具有)

您可以尝试这样的方法。

#include <iostream>
class A
{
    virtual void visit() = 0;
};
class B: private A
{
public:
    void visit()
    {
        std::cout << __PRETTY_FUNCTION__ << "n";
    }
};
class C: private A
{
public:
    void visit()
    {
        std::cout << __PRETTY_FUNCTION__ << "n";
    }    
};
template <typename... Args>
class MyVisitor : public Args...
{
   public:
       template <typename T>
           void visit(T* t)
       {
           t->visit();
       }
};
int main()
{
    MyVisitor<B, C> visitor;
    B b;
    B* bp = &b;
    visitor.visit(bp);
    return 0;
}

实例

您可以完全应用访问者模式:

class B;
class C;
class IVisitor
{
public:
    void visit(B&) = 0;
    void visit(C&) = 0;
};
class A
{
    virtual ~A() = default;
    virtual void accept(IVisitor& v) = 0;
};
class B: public A{ void accept(IVisitor& v) override { v.visit(*this); } };
class C: public A{ void accept(IVisitor& v) override { v.visit(*this); } };