Boost C++ Libraries Home Libraries People FAQ More

Next

Chapter 1. Boost.Optional

Fernando Luis Cacciola Carballal

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

目錄

動機
發展
模型
語義
接口
概要
詳細語義
例子
可選返回值
可選局部變量
可選數據成員
避免不必要的昂貴的缺省構造
Optional 引用
optional 引用的賦值操作的重綁定語義
就地創建
關於 optional<bool> 的說明
異常安全性保證
類型要求
實現說明
依賴性和可移植性
鳴謝

請看一下以下幾個返回一個值的函數,它們也可能沒有值可以返回:

  • (A) double sqrt(double n );
  • (B) char get_async_input();
  • (C) point polygon::get_any_point_effectively_inside();

通常有幾種不同的方法來處理無值可以返回的情形。

最典型的方法是將有效的返回值視為後續條件,則如果函數不能計算出要返回的值,那麼它要麼具有未定義行為(也可以在調試的構建中使用斷言),要麼使 用運行期檢查並在違反後續條件時拋出一個異常。對於函數(A)這是一個合理的選擇,因為無法得到正確的返回值是直接由無效的參數(超出參數域)所引起的, 所以要求調用者只能提供有效域內的參數是適合的。

但是對於函數(B),由於它本身的異步性,不應該僅僅因為不能找到可返回的值就認為是失敗;所以將這種情況視為錯誤或拋出異常都是不正確的。該函數必須返回,並且一定要通知調用者它沒有返回一個有意義的值的。

類似的情形也發生在函數(C)上:詢問一個空的多邊形並返回一個內部點在概念上是錯誤的,但是在多數應用程序中,由於性能的原因,將它視為一個錯誤 是不切實際的(因為在調用之前檢測一個多邊形是否為空可能代價很高),要麼返回任意一個點(通常是無限遠),要麼以高效的方法通知調用者沒有這樣的點。

有多種機制來讓函數通告返回值是無效的。其中最常用的一種機制沒有或只有很小的開銷,就是用一個保留的特殊值來通告。這種特殊值的一個典型例子包括 EOF, string::npos, 位於無限遠的點,等等...

如果存在這樣的值,即返回類型可以持有所有有意義的值再加上這個信號值,那麼這種機制就非常適合。不幸的是,有些情形下不存在這樣的值。這時,通常可用的方法是,要麼使用一個更寬的類型,如用 'int' 代替 'char'; 或者使用復合類型,如 std::pair<point,bool>.

返回一個 std::pair<point,bool>, 要在結果之後添加一個布爾標誌,用於表示該結果是否有效,該方法的好處是,無論函數要返回什麼類型,都可以用作 pair 的第一個元素,這可以成為一種通用的慣用法。例如,前例中的後兩個函數可以具有以下接口:

std::pair<char,bool> get_async_input();
std::pair<point,bool> polygon::get_any_point_effectively_inside();

這些函數使用了統一的接口來處理返回值不存在的可能性:

std::pair<point,bool> p = poly.get_any_point_effectively_inside();
if ( p.second )
    flood_fill(p.first);

不過,這不僅是語法上的負擔,還會容易出錯,因為用戶很容易不檢查函數結果(pair的第一個元素)是否有效就直接使用它。

顯然,我們需要更好的方法。

Last revised: October 10, 2008 at 20:53:37 GMT


Next