派生类的受保护成员未知 [英] Protected member is unknown for derived class

查看:110
本文介绍了派生类的受保护成员未知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为Graphs找到了一个开源类库。当我把它包含在我的项目中有很多错误,我试图修复它们。但是有一个编译错误,我无法解决它。



基类:

 code> template< typename K,typename W,typename T> 
class _base_graph
{
// ...

protected:
std :: map< K,T&点头;
std :: list< edge> edg;
};

派生类:

  template< typename K,typename T = void *> 
class graph:public _base_graph< K,void *,T>
{
// ...
public:
void add_edge(const K& k1,const K& k2);
};

方法体:

  template< typename K,typename T> 
void graph< K,T> :: add_edge(const K& k1,const K& k2)
{
if(nod.find(k1)== nod.end | nod.find(k2)== nod.end())//< - error!
throw std :: string(add_edge:Node does not exist);

// ...
}

编译器显示一个错误:


错误:'nod'未在此范围内声明




您可以在在线编译器中查找和测试mycode

解决方案

您需要

  this-> nod.find(k2); 

  _base_graph< K,void *,T> :: nod.find ....; 

基类和派生类是模板,在您的代码中 nod 是一个非依赖的名称,因此在 graph 的声明处查找。这是两相查找的第一阶段。在这个阶段,编译器(假设它遵循标准的名称查找规则)不可能知道 nod 意味着,因为它不考虑基类直到第二阶段。因此,有必要告诉编译器在第二阶段应该查找 nod 。为此,我们通过使用上面的表单之一明确地告诉它 nod 是在基类中。



这种行为的原因是,在派生类'定义的时候,不可能知道 _base_graph< K,void *,T& / code>包含,以允许添加甚至隐藏名称的模板的特殊化。因此,当所有信息都可用时,上面的技巧确保在派生类实例化的时候查找这些名称。



总之,有两个在这里玩的问题:


  1. nod 不是一个依赖的名称,

  2. 声明 nod 的基类模板在第二阶段之前不可用,因此


  3. 使用 this-> nod _base_graph< K,void *,T> :: nod ,我们显式地处理一个依赖名称,迫使查找在第二阶段发生。



    查看第7到10点这里



    感谢@ DavidRodriguez-dribe来澄清两阶段查询的一些细节。


    I found an open source class library for Graphs. When I included it in my project it has many errors and I tried to fix them. But there is a compile error that I can not solve it.

    Base class:

    template <typename K, typename W, typename T>
    class _base_graph
    {
    //... 
    
    protected:
        std::map<K, T> nod;
        std::list<edge> edg;
    };
    

    Derived class:

    template <typename K, typename T = void*>
            class graph : public _base_graph<K, void*, T>
    {
    //...
    public:
        void add_edge(const K& k1, const K& k2);
    };
    

    Method body:

    template <typename K, typename T>
    void graph<K, T>::add_edge(const K& k1, const K& k2)
    {
        if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end()) // <-- error!!
            throw std::string("add_edge: Node does not exist");
    
        // ...
    }
    

    But my gcc compiler show me an error:

    error: ‘nod’ was not declared in this scope

    You can find and test mycode in this online compiler.

    解决方案

    You need

    this->nod.find(k2);
    

    or

    _base_graph<K, void*, T>::nod.find ....;
    

    The base and the derived classes are templates, and in your code nod is a non-dependent name, and so is looked up at the point of graph's declaration. This is the first phase of the two-phase lookup. At this stage, it is impossible for the compiler (provided it follows the name lookup rules of the standard) to know what nod means, because it does not consider the base class until the second phase. So it is necessary to tell the compiler that nod should be looked up in the second phase. To do this, we explicitly tell it that nod is in a base class by using one of the forms above.

    The reason for this behaviour is that at the point of the derived class' definition, it should not possible to know what _base_graph<K, void*, T>:: contains, to allow for specializations of the template that add and even hide names. So the trick above makes sure that the names are looked up at the point of the derived class' instantiation, when all the information is available.

    In summary, there are two issues in play here:

    1. nod is not a dependent name, so it would be looked up in the first phase.
    2. The base class template, which declared nod, is not available until the second phase, so the name cannot be resolved.

    By using this->nod or _base_graph<K, void*, T>::nod, we are explicitly dealing with a dependent name, forcing the lookup to take place in the second phase.

    See points 7 to 10 here.

    Thanks to @DavidRodriguez-dribeas for clarifying some of the finer points of the two phase look-up.

    这篇关于派生类的受保护成员未知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆