我幾乎對所有東西都使用typedefs,包括函數。在過去的幾周裏,我一直在調整我們的C++代碼,使其最終草稿(N3242)作爲指導,儘可能符合ISO C++ 11標準。使用默認參數的C++函數的多重聲明
正如我們所知,偶爾會有多個聲明通過externs出現在多個文件或重複的typedefs中進入我們的代碼。據第7.1.3節,上面DOCO 145頁的摘錄,這應該是無害的:
3. In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.
[ Example:
typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I;
— end example ]
所以,我寫了一個程序來測試這一點。在最簡單的形式:
typedef int (fcntype)(int, int);
extern fcntype fcn1;
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2, 3); }
編譯使用gcc與
-Wfatal-errors -Wswitch-default -Wswitch-enum -Wunused-parameter -Wfloat-equal -Wundef -c -Wstrict-null-sentinel -std=c++0x -pedantic -Wall -Wextra
有,當然沒問題。讓我們來重複decl函數:
typedef int (fcntype)(int, int);
extern fcntype fcn1;
extern fcntype fcn1; // woops. probably from an #include ...
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2, 3); }
正如標準預測的那樣,沒有問題。讓我們對原文做出不同的改變:
typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2); } // use the default param
再次,沒有問題。問題來了,當我們有重複的東方電氣和這樣的默認的參數都:
typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
extern fcntype fcn1; // FYI this is line 3 in the error message below.
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2); } // use the default param
和GCC與
decltest.cpp:3: error: default argument given for parameter 2 of ‘int fcn1(int, int)’
當然抱怨,我清理代碼的方式應該是清理,這就是說我正在將decl合併爲一個更好的組織文件。但是,這是編譯器中的一個錯誤,還是我對一個默認參數「是」的誤解?
此外,腳註101(在同一頁上):「這意味着默認參數不能出現,例如,在函數指針聲明,對函數的引用或typedef聲明中。所以我認爲'typedef int(fcntype)(int,int = 0);'本身已經不能編譯。或者我錯過了什麼? – Sven
啊,是的。特別感謝您參考標準。我突出了它。令人着迷的是,這些東西是如何在你身上蔓延的,這是一段時間內通過代碼來清理事情的很好的論據。 –