【问题标题】:How function overload resoultion takes place in C++?在 C++ 中如何进行函数重载解析?
【发布时间】:2011-08-08 16:45:58
【问题描述】:

我是 C++ 的初学者。我想知道,函数重载在 C++ 内部是如何发生的

【问题讨论】:

  • 关于重载解析如何在 C++ 中工作的规范长达 30 页,并且与该语言的许多其他部分(名称查找、模板实例化和特化、依赖名称)紧密耦合。重载解决方案的完整解释需要一本书。部分解释(无论是高级解释还是对一小部分重载解决方案的解释)很可能是不正确的。
  • 我认为这有点模糊。您特别想知道什么?实施细节(哪个实施)?还是语言语义(我们可能整个星期都在这里)?
  • 关于这个主题的最佳高级概述可以在 C++ Templates -- The Complete Guide 的附录 B 中找到,它将重载解决方案的基础知识浓缩为非常易读的 10 页。

标签: c++ function overloading


【解决方案1】:

我建议你阅读C++ Primer。这个概念得到了深入的解释。

在更高的层次上,如果两个函数都允许函数重载

  • 同名
  • 在同一范围内声明
  • 有不同的参数列表。

在较低级别(在编译器如何计算它的内部),它是如何完成的。

函数重载解析有3个步骤。

e.g void f();   
    void f(int);
    void f(double, double = 3.4);
    void f(char *, char *);

    Function call inside main -> void f(5.6);
  1. 标识考虑调用的重载函数集,它们被称为候选函数。候选函数是与被调用函数同名的函数,其声明在调用点可见。 它还标识了函数调用中参数列表的属性,即没有参数及其类型。

    已选择:名称为“f”的所有 4 个函数

  2. 从步骤 1 中找到的候选函数集中选择函数,该函数可以使用调用中指定的参数进行调用。这些被称为可行功能。 一个可行的函数是一个与实际函数调用中的参数相比具有相同参数或更多参数(addn 参数具有关联的默认参数)的函数。参数类型必须是可转换的,才能将函数归类为可行。

    已选择:void f(int) 和 void (double, double =3.4)

  3. 在所有可行函数中确定最佳可行函数。 对于 (int) 转换需要应用标准转换(双精度到 int)。但是对于 (double, double=3.4),存在完全匹配,因此不需要转换。没有转换比转换更好。

    已选择:void (double, double = 3.4)

【讨论】:

  • 我认为 OP 是在询问编译器如何知道正在调用哪个版本的函数
  • .. 并具有相同的返回类型
  • 最后一点(返回类型相同)不是必须的——重载的函数可能有不同的返回类型。返回类型本身对重载决议没有影响;只有参数类型很重要。
  • 当然,最后一步是最可怕的,因为整数提升和转换规则之间的规则太多了,以及它们之间发生的排名:/
  • 在 fatc 中,有一个 不同的 返回类型是不允许的,它可能是最常见的。例如。 float sin(float); double sin(double)T operator+(T,T) 用于许多类型的 T。
【解决方案2】:

它发生在内部,名称混乱。

对于文件

void blah(int f)
{
}

void blah(double f)
{}

我得到了符号

ethan@EthanPc ~ % nm blah.o   
0000000000000009 T _Z4blahd
0000000000000000 T _Z4blahi

注意 d 代表双精度,而 i 代表整数。

【讨论】:

  • 这是一种常见的解决方案,但不是唯一的。
  • 我什至认为这就是函数重载在磁盘上外部的工作方式,而问题是它在内部的工作方式。编译器可能在内部有一个符号表,其中包含未损坏的名称和类型;损坏的名称仅用于链接器。
猜你喜欢
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多