使用默认参数消除歧义功能

时间:2016-02-24 01:53:44

标签: 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
}

1 个答案:

答案 0 :(得分:1)

他们肯定会受到不同的待遇。

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()。