首先,在C++函數的返回類型在編譯過程中定義這就是爲什麼你不能做這樣的事情
// ...
if (found)
return index;
else
return false;
有幾種方法來解決這個問題。您必須根據您的應用程序進行選擇。第一個需要考慮的是與STL庫一致。容器爲其元素提供迭代器,並且find
將迭代器返回到所請求的元素。如果找不到,它會將一個迭代器返回到容器的過去結束元素。例如,可以寫
// on some container that offers the standard interface
auto it = container.find(value);
if (it == container.end()) {
// not found
}
以上是最乾淨的解決方案。這是如何在STL中的std::vector
和其他每個容器發出未找到的值。編寫這樣的代碼的主要優點是可以用其他代碼替換容器,代碼仍然可以工作。或者,如果您使用兼容接口設計自己的容器,則可以將其無縫插入現有代碼。
但是,在其他情況下,這可能無法正常工作。例如,您可能只需要實際的索引,並且可能很難從非連續容器上的迭代器獲取。在這種情況下,您可以使用std::optional
。它可以包含一個對象或是空的,並提供一個bool
轉換以便於檢查。
std::optional<int> my_find(T value) {
// ...
if (found) // pseudo-condition, depends on the rest of the code
return std::optional<int>(index); // explicit, could be more compact
else
return std::optional<int>(); // default optional is empty
}
// elsewhere
auto i = my_find();
if (!i) {
// not found
}
請注意,上述內容將增加空間開銷以追蹤對象是否存在。如果由於任何原因而無法接受,則可以採用標記值的思想並創建一個緊湊的可選對象,其中標記值在內部用於指示不存在值,並且提供一個接口來檢查該值,並且可能是如果用戶在對象爲空時請求該值,則拋出。類似於
template <typename T, T sentinel_value>
class CompactOptional {
private:
T value;
public:
CompactOptional(value = sentinel_value): value(value) {}
operator bool() { return value != sentinel_value; }
// getter and setter according to your needs
}
您必須決定當您嘗試獲取不存在的值時會發生什麼,然後就是這樣。前哨值是你不能使用的任何東西,如果使用unsigned
,可能是整數類型的最大值。
你不*使用'-1'。你可以選擇'-32768'或其他一些魔術數字。此外,您可以拋出異常或返回可選對象。 – juanchopanza
你不是真的在浪費它們,除非你可以使用*小*無符號數據類型。在這種情況下,如果找不到該值,可以引發異常。這在概念上更簡潔(將錯誤條件與預期返回值分開),但我不記得這是否是C++中流行的習慣用法。 – chepner
不,'如果我們想表示沒有價值,那麼我們使用-1'並不準確。請注意,string.indexOf在Javascript中也返回-1,因此您可能想要考慮這是爲什麼。 -1表示「沒有價值」的結論是不正確的。 – pvg