模板类扩展基类,重写带有模板参数的虚拟函数,在Clang上发出警告(在GCC上没有)

时间:2019-12-24 23:49:37

标签: c++ templates variadic-templates

我在下面粘贴了一个最小化的示例,还在https://godbolt.org/z/tGCMiU上粘贴了 我在clang ++上收到“隐藏的重载虚拟函数...在第一个参数处类型不匹配”,但在g ++上却什么也没有。

至少在这个小例子中,两个编译器都生成可打印预期结果的代码(两次“ DerivedVisitor覆盖”)。

我想知道警告是否是虚假的,如果是这样,如何在不完全禁用警告的情况下将其静音,或者我是否使用了不确定的行为/做错了什么。

我在下面解释我在做什么以及为什么要这么做

#include <cstdio>

class A;
class B;

class BaseVisitor {
public:
    virtual void visit(A*) {
        printf("foo visit A\n");
    }
    virtual void visit(B*) {
        printf("foo visit B\n");
    }
};

class A {
public:
    void accept(BaseVisitor* v) {
        return v->visit(this);
    }
};

class B {
public:
    void accept(BaseVisitor* v) {
        return v->visit(this);
    }
};

template <typename... T> class DerivedVisitor;

template <typename T, typename... Cdr> class DerivedVisitor<T, Cdr...> : public DerivedVisitor<Cdr...> {
public:
    virtual void visit(T*) override {
        printf("DerivedVisitor override\n");
    };
};

template <> class DerivedVisitor<> : public BaseVisitor {
};

int main() {
    A z;
    B y;
    {
        DerivedVisitor<A, B> b;
        z.accept(&b);
        y.accept(&b);
    }
}

我有一个AST,至少我要打印它,然后从中生成代码/制作CFG。 我不想纠缠在一起,所以我使用了访客模式。

现在有时候我有一个基本/中间类型,我想检查/转换为真实类型。 但是我不想使用RTTI / dynamic_cast。 LLVM does their own RTTI,方法是定义一个枚举并在每个基类中返回对应的枚举值。 但这需要在每个类中定义一个新方法。

要检查某个类,我意识到我可以有一个访问者,该访问者为每个类返回false,然后对其进行扩展并覆盖单个类的方法以返回true。 然后我将其模板化。

然后,我想检查节点是否为多个类之一,因此我使用了上面的可变参数/递归模板。但是,当我使用多个模板类时(在DerivedVisitor<A, B>而非DerivedVisitor<A>DerivedVisitor<B>上警告),我得到警告

0 个答案:

没有答案