2012-11-16 65 views
8

有時,當我用C++編程時,我希望每個變量都有一個undefined的值,比如Javascript !. 例如,當我再次回到了陣外的界限元素的值,它是有用的返回undefined,而不是拋出一個異常,或:返回無效的引用

template <typename T, int SIZE> 
class MyArray 
{ 
    T arr[SIZE]; 
    static T badref; 
public: 
    T &operator[](int i) 
    { 
    if (i >=0 && i < SIZE) 
     return arr[i]; 
    else 
     throw std::string("OUT-OF-BOUNDS"); // or: return badref; !! 
    } 
}; 

另一個骯髒的(在我看來)選項將返回一個預定義變量的引用作爲不良引用變量。我知道我們不能將null或類似的東西分配給參考變量。

是否有另一個格式良好的模式返回引用,其中調用者有能力找出返回的值是無效的?

編輯:我不是指pointer

+5

是的,它被稱爲指針。或者,'boost :: optional'。 – chris

+2

至少讓你的badref對象靜態,那麼它不會佔用你創建的每個MyArray的空間。但我同意,這很醜陋。在這樣的泛型代碼中,我寧願拋出異常 – john

+0

@john:是的,我編輯了它。 – deepmax

回答

5

您可以使用boost ::可選的,因爲在他的評論中提到@克里斯。它是作爲Boost庫的一部分。有關更多詳細信息,請參閱this page

修改類:

template <typename T, int SIZE> 
class MyArray 
{ 
    T arr[SIZE]; 
public: 
    optional<T&> operator[](int i) 
    { 
    if (i >=0 && i < SIZE) 
     return optional<T&>(arr[i]); 
    else 
     return optional<T&>(); 
    } 
}; 

用法:

MyArray<int>() array; 
// fill array with data 

optional<int&> result = array[0]; 
if (result) { 
    // item was found 
} else { 
    // index out of bounds 
} 
+0

badref是什麼? –

+0

@DenisErmolin我個人更喜歡boost :: optional,因爲它明確指出operator []的返回值可能是未定義的,您應該檢查這個條件。 –

+0

@MasoudM。我編輯了我的答案並添加了文檔鏈接。你可以在這裏找到更多關於Boost的信息:http://www.boost.org/doc/libs/1_52_0/index.html –

2

不管你認爲,你的解決方案需要適合的類型系統。所以你的函數簽名必須明確地說(這種或那種)結果可能是T,但它可能是其他的東西。對於

常見方法是:

bool tryGet(int i, T& result); 

  • 而不是返回值的,通過一個「去」參數(的指針或引用)返回一個狀態碼和輸出的值

  • 返回的元組(狀態,值),如:

    std::tuple<bool, T> get(int i) 
    

    (如果。 ouldn't得到,考慮第二元組元素無關 - 需要噸至有一個默認的構造函數)

  • 使用boost::variant(靈活,但需要提升)

  • 使用boost::optional(上述的簡單版本,當你只需要「T或無」)
3

我希望有一個像Javascript這樣的每個變量都有一個未定義的值!

您只有指針(nullptr)的「未定義」值。參考(根據定義)指向有效的實例。

要返回引用靜態對象,你應該將運營商的常量和非const值之間的分離:

template <typename T, int SIZE> 
class MyArray 
{ 
    T arr[SIZE]; 
    static T badref; 
public: 
    T &operator[](int i) 
    { 
    if (i >=0 && i < SIZE) 
     return arr[i]; 
    else 
     // returning ref here would allow clients to write: 
     // MyArray<int> a; 
     // a[-1] = 5; // valid if you return a non-const reference 
     throw std::string("OUT-OF-BOUNDS"); 
    } 
    const T &operator[](int i) const 
    { 
    if (i >=0 && i < SIZE) 
     return arr[i]; 
    else { 
     // MyArray<int> a; 
     // a[-1] = 5; // will not compile (cannot assign to const) 
     static const T invalid = T(); 
     return invalid; 
    } 
    } 

};

0

引用的主要目標是避免無效(NULL)值,同時允許函數修改它們的參數並避免複製數據。如果您需要NULL值,請使用指針。