【问题标题】:Default for resolving ambiguous access解决模糊访问的默认值
【发布时间】:2021-10-15 13:56:17
【问题描述】:

考虑以下类:

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;

不明确的访问问题可以通过using里面MyVisitableGraph来解决:

class MyVisitableGraph : public GraphNode<VisitableGraph, VisitableNode> {
    using VisitableGraph::Visit;
};

但是,有没有办法解决 GraphNode 内部的歧义?我不能只做using G:Visit,因为那时MyOtherGraph 不会编译。例如,是否可以指定默认情况下 G 的优先级应高于 N 以解决 GraphNode 中的歧义?

【问题讨论】:

  • 您遗漏了一些; 并且该方法是私有的。
  • 确实!谢谢:)
  • 我不完全理解这个问题。 visitableGraph.Visit(); 应该总是打电话给VisitableGraph::Visit() 吗?什么时候应该调用VisitableNode::Visit()
  • @463035818_is_not_a_number visitableGraphMyVisitableGraph 类型,它继承自GraphNode,它继承自VisitableGraphVisitableNodeVisitableGraphVisitableNode 都有一个 Visit 成员函数。因此模棱两可。
  • 是的,有歧义,但你说你不想要使用,因为这样只能调用一种方法。你想什么时候给对方打电话?无论如何,看看答案,我希望这就是你要找的

标签: c++ templates multiple-inheritance


【解决方案1】:

正如@463035818_is_not_a_number 所建议的,这个answer 给出了解决方案:

template<class G, class N>
class GraphNode : public G, public N {
public:
    template<class = decltype(&G::Visit)>
    void Visit() {
        G::Visit();
    }
};

它丢失了virtual 说明符,因此它可能并不总是可用。而且它非常hacky,所以我不认为我会使用它。如果说所有歧义都应该通过使用G 而不是N 来解决会更好。

【讨论】:

  • fwiw,SFINAE 起初看起来很老套,但通常它是唯一可行的方法。一旦你习惯了它,它看起来就不再那么老套了。在代码中添加注释,以防您认为它的作用不明显
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多