函数指针的函数重载

bra*_*ron 7 c++ overloading function-pointers

有一个关于重载函数的问题.看看这段代码:

#include<iostream>

void fv(int){}
void fc(const int){}
void fvr(int&){}
void fcr(const int&){}

void fm(void(*fun)(const int))
{
    std::cout << "Constant called" << std::endl;
}

//void fm(void(*fun)(int))
//{
//  std::cout << "non Constant called" << std::endl;
//}

void fm(void(*fun)(const int&))
{
    std::cout << "Constant ref called" << std::endl;
}

void fm(void(*fun)(int&))
{
    std::cout << "non Constant ref called" << std::endl;
}

int main()
{
    fm(&fc);
    fm(&fv);
    fm(&fvr);
    fm(&fcr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果取消注释void fm(void(*fun)(int))函数,你会发现编译器不能通过函数上的指针静态地重载函数,该函数接受参数值和接受const值的函数上的指针.此外,如果您取消注释void(*fun)(const int)并发表评论,void(*fun)(const int)那么所有编译都是成功的.但是,如果我们使用引用它编译好.不明白为什么,你能解释一下吗?这是否意味着通过值和const值接受参数的函数指针是相同的类型?

UPD: 顶级const不影响函数签名 有一个很好的解释为什么应该删除顶级const.

For*_*veR 3

是的,顶级常量将被删除。来自海湾合作委员会的错误

\n\n
\n

重新定义 \xe2\x80\x98void fm(void (*)(int))\xe2\x80\x99

\n
\n\n

正如你所看到的,const 被删除了。

\n\n

引用自 N3376 8.3.5/5

\n\n
\n

生成参数类型列表后,任何修改参数类型的顶级 cv 限定符都会在形成函数类型时被删除。

\n
\n

  • 如果你比较函数参数`T*`和`T const*`或者`T&amp;`和`T const&amp;`,你会发现它有很大的不同。如果您比较“T”和“T const”,也存在差异,但差异很小并且对调用者不可见,因此标准只是说它不会产生不同的函数签名。同样,“T*”和“T*const”也没有什么区别。请注意,“T&amp;”和“T&amp;const”无法进行比较,因为后者根本不存在。 (2认同)