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

标签 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) 不知何故。但我的印象是函数签名包含参数类型,因此这种屏蔽应该发生在这里。对于基类方法来说这不正确吗?

最佳答案

不,这是不正确的:当在同一作用域中声明具有相同名称的函数时,会发生名称隐藏:此处 print in Derived hides Baseprint

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

您可以使用 using 声明将基函数的声明引入派生函数中:

using Base::print

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

有关为什么在这种派生/基础情况下发生隐藏的详细信息,我建议 this other SO post这完美地回答了这个问题。

就标准而言,该特定规则在第 3.3.1 节中定义:

Name hiding [basic.scope.hiding]

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).

关于c++ - 编译器无法通过 ADL 找到基类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24129551/

相关文章:

c# - 如何返回以接口(interface)为返回类型的接口(interface)的实现?

c++ - 为什么 ADL 不能使用未命名的 initializer_list?

c++ - 函数重载 - 传递常量与传递变量 C++

jquery - 如何使用 jQuery 动态地将 css 行高分配给嵌套对象?

c++ - 验证用户的输入以确保它是二进制的 (C++)

Perl:如何从基类导入子程序?

c++ - 表达式中运算符的 GCC 和 ADL

c++ - "using std::swap"如何启用ADL?

c++ - 对于跨平台游戏,我是否必须使用 OpenGL 数据类型(GLint、CLchar、...)?

c++ - 在 g++ 中更改默认的 C++ 标准