【发布时间】:2018-09-02 12:06:20
【问题描述】:
我正在编写一个模板化的访问者(取决于我们要访问的类型):
#include <iostream>
#include <memory>
#include <vector>
#include <string>
class INode;
class INodeVisitor {
public:
virtual void visit(INode&) = 0;
virtual ~INodeVisitor() = default;
};
template<typename ...Ts>
class TypedNodeVisitor;
template<typename T1, typename ...Ts>
class TypedNodeVisitor<T1, Ts...> : public TypedNodeVisitor<Ts...> {
public:
virtual void visit(INode &v) override {
if(auto p = dynamic_cast<T1*>(std::addressof(v))) {
apply(*p);
}
if constexpr(sizeof...(Ts) != 0) {
TypedNodeVisitor<Ts...>::visit(v);
}
}
//using TypedNodeVisitor<Ts...>::apply;
virtual void apply(T1 &) = 0;
};
template<>
class TypedNodeVisitor<> : public INodeVisitor {};
class INode {
public:
void accept(INodeVisitor &nv) {
nv.visit(*this);
}
virtual ~INode() = default;
};
class NodeB : public INode {};
class NodeA : public INode {};
class DrawerVisitor : public TypedNodeVisitor<NodeA, NodeB> {
public:
void apply(NodeA &) override {
std::cout << "A" << std::endl;
}
void apply(NodeB &) override {
std::cout << "B" << std::endl;
}
};
int main()
{
auto nodeA = std::make_shared<NodeA>();
auto nodeB = std::make_shared<NodeB>();
DrawerVisitor visitor;
nodeA->accept(visitor);
nodeB->accept(visitor);
return 0;
}
当我听到这些警告时:
prog.cc:49:30: note: in instantiation of template class 'TypedNodeVisitor<NodeA, NodeB>' requested here
class DrawerVisitor : public TypedNodeVisitor<NodeA, NodeB> {
^
prog.cc:31:18: note: hidden overloaded virtual function 'TypedNodeVisitor<NodeB>::apply' declared here: type mismatch at 1st parameter ('NodeB &' vs 'NodeA &')
virtual void apply(T1 &) = 0;
我确实了解问题可能是什么,但如果不在 TypedNodeVisitor<> 的空特化中添加伪造的 apply() 定义,我将无法解决它。
有没有办法在using TypedNodeVisitor<Ts...>::apply 上使用std::enable_if?
【问题讨论】:
-
只要我实现了虚拟方法,它就对我有用。 ideone.com/a8U9HG
-
我会将接口应用从访问的实现中分离出来。你想同时做这两件事有理由吗?
-
@super 我编辑了我的帖子。 vdavid 你只使用一个节点,也许这就是你没有警告的原因。 Yakk 我不明白你的建议是什么。你的意思是做一个界面Applyable和一个界面Visitor?这并不容易,因为您可以添加许多不同的类型 :)
-
@Yakk-AdamNevraumont 好的,我想我明白你的意思了。我需要同时做这两件事,但我认为这是因为我有一些设计问题,所以我正在努力:p
标签: c++ templates c++17 variadic-templates sfinae