C++核心準(zhǔn)則ES.107:不要使用無(wú)符號(hào)數(shù)下標(biāo),使用gsl::index更好?

ES.107: Don't use?unsigned?for subscripts, prefer?gsl::index
ES.107:不要使用無(wú)符號(hào)數(shù)下標(biāo),使用gsl::index更好
Reason(原因)
To avoid signed/unsigned confusion. To enable better optimization. To enable better error detection. To avoid the pitfalls with?auto?and?int.
為了避免有符號(hào)數(shù)/無(wú)符號(hào)數(shù)混用帶來(lái)的問(wèn)題。有利實(shí)現(xiàn)更好的優(yōu)化和錯(cuò)誤檢查。避免auto和int類型帶來(lái)的陷阱。
Example, bad(反面示例)
vector vec = /*...*/;
for (int i = 0; i < vec.size(); i += 2) // may not be big enough
cout << vec[i] << '\n';
for (unsigned i = 0; i < vec.size(); i += 2) // risk wraparound
cout << vec[i] << '\n';
for (auto i = 0; i < vec.size(); i += 2) // may not be big enough
cout << vec[i] << '\n';
for (vector::size_type i = 0; i < vec.size(); i += 2) // verbose
cout << vec[i] << '\n';
for (auto i = vec.size()-1; i >= 0; i -= 2) // bug
cout << vec[i] << '\n';
for (int i = vec.size()-1; i >= 0; i -= 2) // may not be big enough
cout << vec[i] << '\n'; Example, good(范例)
vector vec = /*...*/;
for (gsl::index i = 0; i < vec.size(); i += 2) // ok
cout << vec[i] << '\n';
for (gsl::index i = vec.size()-1; i >= 0; i -= 2) // ok
cout << vec[i] << '\n'; Note(注意)
The built-in array uses signed subscripts. The standard-library containers use unsigned subscripts. Thus, no perfect and fully compatible solution is possible (unless and until the standard-library containers change to use signed subscripts someday in the future). Given the known problems with unsigned and signed/unsigned mixtures, better stick to (signed) integers of a sufficient size, which is guaranteed by?gsl::index.
內(nèi)置數(shù)組使用有符號(hào)數(shù)下標(biāo)。標(biāo)準(zhǔn)庫(kù)容器使用無(wú)符號(hào)數(shù)下標(biāo)。因此不存在完美、完全兼容的解決方案(除非將來(lái)某一天標(biāo)準(zhǔn)庫(kù)容器轉(zhuǎn)而使用有符號(hào)數(shù)下標(biāo))??紤]到使用無(wú)符號(hào)數(shù)或者有符號(hào)數(shù)/無(wú)符號(hào)數(shù)混合可能帶來(lái)的問(wèn)題,較好的選擇是賦予(有符號(hào))整數(shù)足夠大的空間,這一點(diǎn)可以通過(guò)使用gsl::index保證。
Example(示例)
template
struct My_container {
public:
// ...
T& operator[](gsl::index i); // not unsigned
// ...
};Example(示例)
??? demonstrate improved code generation and potential for error detection ???Alternatives(其他選項(xiàng))
Alternatives for users
利用者角度的其他選項(xiàng)
use algorithms
使用算法
use range-for
使用范圍for
use iterators/pointers
使用指針和迭代器
Enforcement(實(shí)施建議)
Very tricky as long as the standard-library containers get it wrong.
如果標(biāo)準(zhǔn)庫(kù)容器出問(wèn)題了,很難檢出。
(To avoid noise) Do not flag on a mixed signed/unsigned comparison where one of the arguments is?sizeof?or a call to container?.size()?and the other is?ptrdiff_t.
(為了避免誤檢出)如果一個(gè)操作數(shù)是sizeof或者container.size()而另一個(gè)操作數(shù)是ptrdiff_t,不要標(biāo)記有符號(hào)數(shù)/無(wú)符號(hào)數(shù)混合的比較操作。
原文鏈接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es107-dont-use-unsigned-for-subscripts-prefer-gslindex
覺(jué)得本文有幫助?請(qǐng)分享給更多人。
關(guān)注微信公眾號(hào)【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_(kāi)發(fā),面向?qū)ο笏伎迹?/span>
