【问题标题】:Inherited member function seems undeclared, what is going on? [duplicate]继承的成员函数似乎未声明,这是怎么回事? [复制]
【发布时间】:2016-11-24 21:30:11
【问题描述】:

我想编译一个 C++ 软件,它可以让我进行几次编译 错误。此错误与无法解析的成员函数有关。

这个问题应该包含回答它所需的所有内容。然而,如果那 确实是这样,我现在应该已经找到答案了。所以请放心 浏览source code。 这个问题中的所有代码都不是我的,而是根据 GPLv2 许可的。

我编译的系统是运行 Red Hat Enterprise Server 的 IBM PowerPC 740 6.8.使用模块,我启用了 Clang 3.7。一切都被交叉编译 对于 IBM PowerPC A2 芯片,它是 IBM BlueGene/Q 超级计算机。那些事 应该由我的compilation script照顾 这设置了许多需要的configureCXXFLAGS

当前状态下的编译错误(提交 fee0a02) 是这个:

bfmcommqmp.C:183:5: error: use of undeclared identifier 'gather'
    gather(result_cb, psi, dag);
    ^

违规行在bfmcommqmp.C 的此方法定义中:

168 template <class Float>                                                          
169 void bfmcommQMP<Float>::comm_start(int result_cb, Fermion_t psi, int dag) {     
170     // gather the faces. Routines here are threaded.                            
171     // All threads cooperate in gathering.                                      
172                                                                                 
173     //  if ( this->isBoss() && (me == 0)) {                                     
174     //    this->Error("comm_start checking heap\n"); fflush(stdout);            
175     //    mcheck_check_all();                                                   
176     //    this->Error("comm_start mcheck_all");fflush(stdout);                  
177     //  }                                                                       
178                                                                                 
179     int me = this->thread_barrier();                                            
180                                                                                 
181     this->thread_barrier();                                                     
182                                                                                 
183     gather(result_cb, psi, dag);                                                
184                                                                                 
185     this->thread_barrier();                                                     
186     if (me == 0) {                                                              
187         comm_qmp_start(psi);                                                    
188     }                                                                           
189     this->thread_barrier();                                                     
190                                                                                 
191     return;                                                                     
192 }

这当然是bfmcommQMP 类的一部分。看着相关的 头文件bfmcommqmp.h,找到这个类声明:

  8 template <class Float>                                                          
  9 class bfmcommQMP : public bfmbase<Float> {                                      
 10   public:                                                                       
 11     // QMP thingy-me-bob's                                                      
 12     QMP_msghandle_t multi_handle[2];                                            
 13                                                                                 
 14     QMP_msgmem_t send_ops_msgmem_t[8];                                          
 15     QMP_msgmem_t recv_ops_msgmem_t[8];                                          
 16                                                                                 
 17     QMP_msghandle_t send_multi_handle;                                          
 18     QMP_msghandle_t send_handles[8];                                            
 19                                                                                 
 20     QMP_msghandle_t recv_handles[8];                                            
 21     QMP_msghandle_t all_handles;                                                
 22                                                                                 
 23     Float *simd_rbuf[8];                                                        
 24     Float *receive_area;                                                        
 25                                                                                 
 26     int num_op;                                                                 
 27                                                                                 
 28     virtual bool isBoss();                                                      
 29                                                                                 
 30     virtual void recv_init(void);                                               
 31     virtual void recv_end(void);                                                
 32                                                                                 
 33     virtual void comm_init(void);                                               
 34     virtual void comm_end(void);                                                
 35     virtual void comm(int result_cb, Fermion_t psi, int dag);                   
 36     virtual void comm_start(int result_cb, Fermion_t psi, int dag);             
 37     virtual void comm_qmp_start(Fermion_t psi);                                 
 38     virtual void comm_qmp_complete(void);                                       
 39     virtual void comm_merge(void);                                              
 40     virtual void comm_complete(int result_cb, Fermion_t psi);                   
 41     virtual void comm_gsum(double &val);                                        
 42     virtual void comm_gsum(double *val, int N);                                 
 43 };

它继承自bfmbase。跳转到文件bfm.h 包含在 bfmcommqmp.h,我们找到类定义,其中包含两个gather 方法:

 133 template <class Float>                                                          
 134 class bfmbase : public bfmarg, public ThreadModel {                             
 135   public:  

 282     void gather(int result_cb, Fermion_t psi, int dag);
 283     void gather(int mu, int result_cb, Fermion_t psi, int dag); 

1018 };

据我了解,bfmcommQMP 类应该继承了 来自bfmbase 的非虚函数gather。显然情况并非如此, 否则 Clang 不会抱怨。

我在这里缺少什么?为什么函数gather在里面不可用 bfmcommQMP::comm_start成员函数?

【问题讨论】:

    标签: c++ templates inheritance


    【解决方案1】:

    问题是你的派生类是dependent name。您需要使用this-&gt;gather() 来限定基类中对gather() 的调用,否则编译器不会从基类解析gather()。为了简化,

    template<class T> struct Base
    {
        void f();
    };
    
    template<class T> struct Derived: Base<T> // dependent name
    {
        void foo()
        {
            this->f(); // won't compile without this->
        }
    };
    

    另一种方法是做

    using Base::f;
    

    在派生的Derived::foo() 或限定调用中

    Base::f();
    

    相关:Why do I have to access template base class members through the this pointer?

    【讨论】:

    • 这也解释了为什么该方法中的所有其他调用都以this-&gt;为前缀!现在我得到了一些其他的编译错误,这个似乎已经解决了。非常感谢,我一直在寻找其他地方,没想到可能是这样的原因。
    • 不客气。 C++ Templates: The Complete Guide 是,imo,关于模板的最好的书,告诉你你曾经想知道的关于模板的一切。旧的(2002 年)但仍然非常相关。作者正在对现代 C++(C++11 及更高版本)进行更新。
    猜你喜欢
    • 2015-12-15
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 2016-10-28
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多