c++ - 使用默认参数消除函数歧义

标签 c++

我一直认为默认参数是重载的语法糖。
但它们似乎只是粘在一个函数(类型)之上——一个没有提供它们的函数。
出现这种情况有充分的理由吗?

void foo(int i);// void (*)(int)
void foo();// void (*)()
void bar(int i = false);// void (*)(int)

int main() {
    return static_cast<void(*)()>(&foo) // works
        && static_cast<void(*)()>(&bar);// doesn’t work
}

最佳答案

肯定是区别对待的。

void foo(int i);// void (*)(int)
void foo();// void (*)()

这些调用在链接时解析,链接器会将它们链接到不同的函数,因为它们是不同的函数。

void bar(int i = false);// void (*)(int)

它是在编译时解决的,如果你不提供额外的参数,编译器会添加额外的参数,所有的调用都会链接到同一个函数。

因为添加额外参数的是编译器,所以编译器必须知道默认参数,它必须在编译时可见。

示例代码:

% cat t.cpp
void foo(int i);// void (*)(int)
void foo();// void (*)()
void bar(int i = false);// void (*)(int)

int main() {
    foo(0);
    foo();
    bar(0);
    bar();
}

编译结果:

% objdump -C -r t.o

t.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
000000000000000a R_X86_64_PC32     foo(int)-0x0000000000000004
000000000000000f R_X86_64_PC32     foo()-0x0000000000000004
0000000000000019 R_X86_64_PC32     bar(int)-0x0000000000000004
0000000000000023 R_X86_64_PC32     bar(int)-0x0000000000000004


RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE 
0000000000000020 R_X86_64_PC32     .text

有foo()和foo(int),但只有bar(int),没有bar()。

关于c++ - 使用默认参数消除函数歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35591830/

相关文章:

c++ - 对这 n^2 个数字进行排序的最快方法是什么?

c++ - ASM at&t 语法

c++ - 如何编译 SCIP 以获得类似于 SCIP 网站上提供的二进制包 (Windows)

c++ - C++ 类中动态位集的声明和赋值

C++结构类型重定义错误

c++ - 函数参数可以是多种类型吗?

c++ - GCC 中普通可复制类型的原子对象

c++ - 由 const std::unique_ptr 管理的对象的生命周期

c++ - 使用 ptr_vector 时访问派生类的方法

c++ - 在 ui 文件中隐藏 QTabWidget 中的单个选项卡 Pane ?