为什么参数修饰符(即'const'或'volatile')不被视为函数类型或签名的一部分?

时间:2012-12-04 16:07:46

标签: c++

请注意,以下两个函数具有相同的类型和签名:

void foo1(int t) {} // foo1 has type 'void(*)(int)', and signature '(*)(int)'
void foo2(const int t) {} // Also type 'void(*)(int)', signature '(*)(int)'

const不是函数类型或函数签名的一部分)。同样,返回类型的修饰符(constvolatile)不会影响函数类型或函数签名。

但是,在函数定义本身(未显示)中,命名变量t确实在const中保持foo2限定。

有许多StackOverflow问题讨论为什么函数的返回类型不被视为函数签名的一部分(用于重载解析)。

但是,我找不到任何StackOverflow问题,询问为什么参数修饰符(constvolatile)不是函数类型或签名的一部分。另外,我直接查看了C ++ 11标准文档,发现很难解开。

参数修饰符(即constvolatile)不属于函数的类型或签名这一事实背后的理由是什么?

ADDENDUM 为了清楚起见,从下面的R.MartinhoFernandes的回答中,我应该澄清一下,在C ++(我认为)中,参数修饰符constvolatile仅作为一部分被忽略功能类型/签名如果是顶级修饰符 - 请参阅下面的答案。

1 个答案:

答案 0 :(得分:11)

  

参数修饰符(即const和volatile)不是函数类型或签名的一部分,背后的基本原理是什么?

从来电者的角度来看,void foo(int)void foo(int const)之间没有区别。无论你传递给它的是什么,都不会被修改,无论修饰符如何:该函数都会得到一个副本。

从实施者的角度来看,唯一的区别是使用void foo(int x),您可以在正文中变异x(即您的本地副本),但不能使用{{1}变异x }。

C ++承认这两个观点。通过使两个声明void foo(int const x)void foo(int);声明相同的函数来确认调用者的观点。通过允许您将函数声明为void foo(int const);来确认实现者的视角,但如果您想确保不会意外地分配参数,则将其定义为void foo(int x);

请注意,这仅适用于适用于整个类型的顶级void foo(int const x) { /*...*/ },即const。在constint const&之类的东西中,修饰符仅适用于类型的一部分,作为“指向(const(int))的指针”,因此它不是顶级int const*。但是在const中,int *const再次适用于整个类型,如“const(指向(int))”。