我在下面粘贴了一个最小化的示例,还在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>
上警告),我得到警告