编译器无法通过ADL找到基类方法

时间:2014-06-09 21:41:38

标签: c++ inheritance argument-dependent-lookup

这里发生了什么 - 为什么这不能编译?

#include <iostream>
class Base {
    void print(double d) {
        std::cout << "Base: " << d << std::endl;
    }
};

class Derived : public Base {
void print(std::string const & str) {
        std::cout << "Derived: " << str << std::endl;
    }
};

int main(int argc, char* argv[]) {
    Derived d;
    d.print(2.);
    d.print("junk");
}

(MinGW和VC11中的错误等同于No conversion from double to std::string。)

如果我在Derived中更改了打印功能的名称,则会成功编译,因此Derived::print(string const &)显然会以某种方式屏蔽Base::print(double)。但我的印象是函数签名包含参数类型,所以这里应该进行掩码。在基类方法的情况下,这是不正确的吗?

1 个答案:

答案 0 :(得分:3)

不,它不正确:当在同一范围内声明具有相同名称的函数时发生名称隐藏:print中的Derived 隐藏 {{ 1 {} print

在函数查找的第(一)步中忽略参数名称/类型。

您可以使用Base声明在Derived中声明Base函数的声明:

using

如果这样做,将会定期进行重载解析。

有关为什么隐藏发生在此Derived / Base情况中的详细信息,我建议this other SO post完美地回答它。

至于标准,这个特殊规则在3.3.1节中定义:

  

名称隐藏 [basic.scope.hiding]

     

可以通过嵌套声明性区域中相同名称的显式声明来隐藏名称   或派生类(10.2)。