Consider the following classes:
class VisitableNode {
public:
virtual void Visit();
};
class VisitableGraph {
public:
virtual void Visit();
};
class OtherNode {
};
class OtherGraph {
};
template<class G, class N>
class GraphNode : public G, public N {
};
class MyVisitableGraph : public GraphNode<VisitableGraph, VisitableNode> {
};
class MyOtherGraph : public GraphNode<OtherGraph, OtherNode> {
};
MyVisitableGraph visitableGraph;
visitableGraph.Visit(); // Ambiguous access. Could be either VisitableGraph::Visit or VisitableNode::Visit.
MyOtherGraph otherGraph;
The ambiguous access issue can be solved with using
inside MyVisitableGraph
:
class MyVisitableGraph : public GraphNode<VisitableGraph, VisitableNode> {
using VisitableGraph::Visit;
};
But, is there a way to resolve the ambiguity inside GraphNode
instead? I can't just do using G:Visit
, as then MyOtherGraph
would not compile. Is it for example possible to specify that by default, G
should have higher precedence than N
in order to resolve ambiguities in GraphNode
?
As suggested by @463035818_is_not_a_number, this answer gave a solution:
template<class G, class N>
class GraphNode : public G, public N {
public:
template<class = decltype(&G::Visit)>
void Visit() {
G::Visit();
}
};
It loses the virtual
specifier, so it might not always be usable. And it is very hacky, so I don't think I'll use it. A way to say that all ambiguities should be resolved by using G
over N
would have been nicer.