2010-10-08 27 views
7

只是一個簡單的問題。有功能嘗試塊,但不在構造函數

void f(Foo x) try 
{ 
    ... 
} 
catch(exception& e) 
{ 
    ... 
} 

void f(Foo x) 
{ 
    try { ... } 
    catch (exception& e) 
    { 
     ... 
    } 
} 

之間有什麼區別?

如果否,爲什麼函數嘗試塊(用於構造函數的初始化列表的情況被放在一邊)?如果x傳遞給fFoo的複製構造函數拋出異常,會發生什麼情況?

回答

9

函數try塊只在構造函數中需要。在所有其他情況下,通過將函數的整個主體封裝在正常的try/catch塊中可以達到完全相同的效果。

如果用於初始化參數的複製構造函數拋出異常,則會發生之前的函數調用。它不能被函數try塊或函數中的異常處理程序捕獲,因爲函數不會被調用。

+5

這意味着功能嘗試對非構造函數塊只是一個替代語法,沒有語義的目的,這可能確實是他們存在的爭論性論據。另一方面,在C++中有太多莫名其妙的東西,即使在與兼容性無關的東西中也是如此。 – 2010-10-08 11:09:21

1

爲了捕獲構造函數初始化列表中的異常,明確添加了函數try塊。

在你的例子中沒有構造函數初始化,所以兩種形式沒有區別。

+0

,它不能解決可能拋出構造函數類的靜態/全局對象問題,因爲無論如何都會重新拋出異常。 – 2010-10-08 11:11:44

+2

@Armen:如果對象無法被初始化,構造函數_要拋出。這是報道施工失敗的唯一途徑。 – 2010-10-08 11:15:37

5

有些事情是允許的,因爲它會更難以禁止它們。在某些函數上允許函數try塊,但不是所有函數體都會使語法和編譯器更加複雜。

+0

好點,那是我首先想到的。 – 2010-10-08 11:14:39

3

在此Dr. Dobb's article(雖然很舊的)就發現了一個有趣的觀點:

...記住你不能返回函數試塊處理程序中的值。因此,它是沒有意義的使用功能try塊的非void函數

,這是他們的代碼示例:

int f() 
try 
{ 
    ... 
} 
catch(Error &e) 
{ 
    // oops, can't return int from here! 
} 

這實際上意味着函數try塊比「定期「試塊,除了在構造函數中應該阻止它們的使用。

(文章是從2000年,因此它會是不錯的,如果有人對這個是否依然那麼在當前的標準評論)

+1

...除非「catch」塊本身無條件地拋出或重新拋出,在這種情況下,函數try塊是寫入這種最簡潔的方式,IMO。 – Nemo 2016-03-16 00:24:08

+2

(評論5年後添加:)我用gcc 5.4測試過 - 在那裏,我可以從catch-block中返回一個值。但是,我沒有研究任何標準。 – ralfg 2016-08-24 07:40:42

+1

這個答案是錯誤的,並且AFAIK在創建時已經是如此了,請看[這裏](http://en.cppreference.com/w/cpp/language/function-try-block),特別是在底部。 – Walter 2016-08-24 08:12:36