您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++返回多個輸出值時為什么最好返回結構體或tuple”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++返回多個輸出值時為什么最好返回結構體或tuple”吧!
返回值本身就表明了自己是一個只用作輸出的值。注意C++是可以同時返回多個值的,通常是使用tuple(包括pair),調用者還可以利用tie獲得額外的便利性。如果返回值有特定的含義時使用命名的結構體會更好。否則無名的tuple會更適合一般的代碼。
譯者注:tie是C++11導入的新特性,可以用于解構tuple元素。
Example(示例)
// BAD: output-only parameter documented in a comment
int f(const string& input, /*output only*/ string& output_data)
{
// ...
output_data = something();
return status;
}
// GOOD: self-documenting
tuple<int, string> f(const string& input)
{
// ...
return make_tuple(status, something());
}
譯者注:類似的返回多值的做法在其他語言(例如Python)中已經廣泛使用。
C++98的標準庫中已經使用這種風格,因為pair就像2個元素的tuple。例如,假設有一個set<string> my_set,考慮下面的代碼:
// C++98result = my_set.insert("Hello");if (result.second) do_something_with(result.first); // workaround
使用C++11你可以這樣寫,直接將結果放入已經存在的局部變量。
Sometype iter; // default initialize if we haven't already
Someothertype success; // used these variables for some other purpose
tie(iter, success) = my_set.insert("Hello"); // normal return value
if (success) do_something_with(iter);
使用C++17,我們可以使用結構化綁定功能定義和初始化多個值:
if (auto [ iter, success ] = my_set.insert("Hello"); success) do_something_with(iter);
有時我們需要向函數傳遞一個對象以便控制這個對象的狀態。在這種情況下,使用引用T&傳遞對象通常是正確的方式。一般不需要一方面明確地傳遞一個輸入/輸出參數,另一方面卻通過返回值輸出。例如:
istream& operator>>(istream& is, string& s); // much like std::operator>>()
for (string s; cin >> s; ) {
// do something with line
}
譯者注:這里說的應該是s。is由于需要支持連續的>>,需要作為返回值返回。
這里s和cin都用作輸入/輸出參數。我們通過(非常量)引用傳遞cin以便控制它的狀態。我們傳遞s以避免重復申請內存。通過重用s(通過引用傳遞),我們只是在需要擴充s的容量時重新申請內存。這個技術有時被稱為“用戶申請的輸出”模式,這種方式特別適用于類似string和vector那樣的類型,它們需要釋放申請到的存儲空間。
作為比較,如果我們使用返回值傳出所有值,差不多需要這樣做:
pair<istream&, string> get_string(istream& is); // not recommended
{
string s;
is >> s;
return {is, s};
}
for (auto p = get_string(cin); p.first; ) {
// do something with p.second
}
我們認為這種做法明顯不夠優雅,也不夠高效。
如果真正嚴格地理解這條準則(F.21), 這個例外并不是真的例外,因為它依賴于輸入/輸出參數,而不是本準則提到的簡單的輸出參數。然而我們強調的是
明確而不是隱含地傳遞的情況。
Note(注意)
很多情況下,傳遞一個明確的,用戶定義的類型可能是有用的。例如:
struct Distance {
int value;
int unit = 1; // 1 means meters
};
Distance d1 = measure(obj1); // access d1.value and d1.unit
auto d2 = measure(obj2); // access d2.value and d2.unit
auto [value, unit] = measure(obj3); // access value and unit; somewhat redundant
// to people who know measure()
auto [x, y] = measure(obj4); // don't; it's likely to be confusing
譯者注:代碼中[x,y]的用法是C++17中引入的結構化綁定(structred binding)
一般的pair和tuple應該只被用于返回值表現獨立實體(數據之間沒什么內在聯系)的情況,而不是表現某種抽象。
另外一個例子,使用和variant<T, error_code>類似的特定類型,而不是使用一般的tuple。
譯者注:variant是C++17引入的新特性。這個例子可以看做抽象之外的另一種包含明確意義的情況。
Enforcement(實施建議)
應該使用返回值代替輸出參數。輸出參數可以是函數寫入動作的對象,調用一個非常量成員函數,或者作為一個非常量傳遞。
感謝各位的閱讀,以上就是“C++返回多個輸出值時為什么最好返回結構體或tuple”的內容了,經過本文的學習后,相信大家對C++返回多個輸出值時為什么最好返回結構體或tuple這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。