2012-12-04 24 views
6

注意以下兩種功能具有相同的類型和簽名:爲什麼參數修飾符(即'const'或'volatile')不被視爲函數類型或簽名的一部分?

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確實在foo2中保留const資格。

有許多StackOverflow的問題,討論爲什麼函數的返回類型不被視爲函數簽名(用於重載決議)的一部分。

但是,我找不到任何StackOverflow問題,詢問爲什麼參數修飾符(constvolatile)不是函數的類型或簽名的一部分。另外,我直接看了C++ 11標準文檔,發現很難解開。

參數修飾符(即constvolatile)不屬於函數的類型或簽名的一部分的基本原理是什麼?

附錄爲了清楚起見,從下面R.MartinhoFernandes的答案,我要澄清,在C++(我認爲)的說法修飾符constvolatile如果他們頂級只忽略作爲函數類型/簽名的一部分級別修飾符 - 請參閱下面的答案。

+3

返回類型*是*函數簽名的一部分。它只是不考慮解決超載問題。這兩個是不同的想法。 –

+0

我不能給你官方的C++答案,但從用戶的角度來看,他們沒有任何區別。如果用戶調用foo1或foo2,用戶將使用int來完成此操作。在實現中,const修飾符會有效果。由於簽名基本上是界面(用戶關心的內容),所以不區分是合理的。 – RonaldBarzell

+0

@ R.MartinhoFernandes我不這麼認爲 - 例如,請參閱http://stackoverflow.com/questions/13687607/is-the-only-purpose-of-a-function-signature-as-opp-to -type-to-define-dupl –

回答

11

參數修飾符(即const和volatile)不屬於函數的類型或簽名的一部分的基本原理是什麼?

從來電者的角度來看,void foo(int)void foo(int const)之間沒有區別。無論你傳遞給它什麼修改器,它都不會被修改:函數將得到一個副本。

從實施者的角度來看,唯一不同的是,void foo(int x)可以發生變異在人體內x(即你的本地副本),但你不能用void foo(int const x)變異x

C++承認了這兩種觀點。通過使兩個聲明void foo(int);void foo(int const);聲明相同的功能來確認來電者的視角。通過允許您聲明一個函數void foo(int x);,但將其定義爲void foo(int const x) { /*...*/ }來確認實現者的角度,如果要確保您不會意外地分配給參數。

請注意,這僅適用於適用於整個類型的頂級const,即const。在int const&int const*之類的東西中,修飾符僅適用於類型的一部分,因爲「指向(const(int))」的指針,因此它不是頂級const。然而,在int *const中,const再次適用於整個類型,如「const(pointer to(int))」中所示。

+0

這個推理是否適用於函數簽名'void foo(const int&)'? –

+1

@Dan no,僅限於所謂的「頂級const」。在'const int&'(又名'int const&')中'const'只適用於被引用的部分('int'),而不是整個類型。 –

+0

謝謝。我不明白「頂級」和非頂級之間的區別。 –

相關問題