为什么我必须作用域重载的模板基类方法? [英] Why must I scope an overloaded template base class method?

查看:27
本文介绍了为什么我必须作用域重载的模板基类方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法在不限定基类的情况下调用基类的方法,这似乎是因为我重载了该方法.如果我不重载该方法,则编译器不会抱怨.这是我想要做的一个例子:

I can't seem to call a method of a base class without scoping to the base class, and it seems that this is because I have overloaded the method. If I do not overload the method then the compiler doesn't complain. Here's an example of what I'd like to do:

struct BaseClass {                                                           
  template <typename T> T& foo(T& t) {                               
    return t;                                                                
  }                                                                          
};                                                                           

class ChildClass: public BaseClass {                                         
  public:
  // The presence of this template causes compiler confusion                                                            
  template <class T> T& foo(T& t, int szl) {                        
    return t;                                                                
  }                                                                          

  template <class T> int bar(T& t) {                 
    // But if I scope this as BaseClass::foo(...) it's all good                        
    return foo(t);                                                
  }                                                                          
};                                                                           

int main() {                                                                 
  int t = 1;                                                                 
  ChildClass c;                                                              
  c.bar(t);                                        
}

如果在 bar(...) 我调用 BaseClass::foo(...) 编译器不会抱怨,但我在这里没有看到任何歧义,所以我很困惑为什么我需要这样做.

If in bar(...) I call BaseClass::foo(...) the compiler does not complain, but I don't see any ambiguity here and so I'm confused as to why I'd need to do this.

推荐答案

当编译器尝试将函数名与函数匹配时,它分两步完成.在第一步中,它找到与给定名称匹配的所有函数.如果找到多个函数,它会尝试重载解析的逻辑来找到最匹配的函数.

When the compiler tries to match a function name with a function, it does so in two steps. In the first step it finds all the functions that match the given name. If it finds more than one function, it tries the logic of overload resolution to find the best matching function.

第一步,如果编译器在类中找到一个名字,它就停止在基类中寻找同名的函数.在您的情况下,由于它在 ChildClass 中找到了 foo,它停止在 BaseClass 中搜索名为 foo 的函数.但是,唯一匹配的foo与调用不匹配,编译器报错.

In the first step, if the compiler finds a name in the class, it stops looking for functions of the same name in base classes. In your case, since it finds a foo in ChildClass, it stops searching for functions named foo in BaseClass. However, the only matching foo does not match the call and the compiler reports an error.

如何解决问题:

  1. 使用您在帖子中描述的方法.调用 BaseClass::foo(...).

BaseClass 中的所有 foo 带入 ChildClass 的作用域.

Bring all the foo from BaseClass into the scope of ChildClass.

class ChildClass: public BaseClass {
  public:

  using  BaseClass::foo;

  template <class T> T& foo(int baz, T& t, int szl) {
     return t;
  }

  template <class T> int bar(T& t) {
    return sizeof(foo(1, t)); // Should work.
  }
};

这篇关于为什么我必须作用域重载的模板基类方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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