[英]What type should I use for iterator difference to eliminate “possible loss of data” warnings?
我需要一個x64模式警告的通用規則。 哪種方式更好?
請考慮以下幾行代碼
const int N = std::max_element(cont.begin(), cont.end()) - cont.begin();
要么
const int ARR_SIZE = 1024;
char arr[ARR_SIZE];
//...
const int N = std::max_element(arr, arr + ARR_SIZE) - arr;
這是我通常的代碼。 我對x86沒有任何問題。
但是如果我在x64模式下運行編譯器,我會收到一些警告:
conversion from 'std::_Array_iterator<_Ty,_Size>::difference_type' to 'int', possible loss of data
conversion from '__int64' to 'int', possible loss of data
我想通過共同的規則來解決這些問題。 哪種方式更好?
制作static_cast
:
const int N = static_cast<int>( std::max_element(cont.begin(), cont.end()) - cont.begin() );
我認為這不是通用的。 還有太多的信件。
用ptrdiff_t
替換輸出類型:
const ptrdiff_t N = std::max_element(cont.begin(), cont.end()) - cont.begin();
那么這個未知類型ptrdiff_t應該怎么做? 那時我會再收到十幾個警告。 我想用N做很多操作:保存,加法,乘法,循環等等。 重要的是:但是如果std::_Array_iterator<_Ty,_Size>::difference_type
和ptrdiff_t
是不同的類型怎么辦?
用std::_Array_iterator<_Ty,_Size>::difference_type
替換輸出類型:
//h-file struct S { type mymember; // What is the type? }; //cpp-file typedef std::vector<int> cont_t; const cont_t::difference_type N = std::max_element(cont.begin(), cont.end()) - cont.begin(); // Save N S mystruct; mystruct.mymember = N; // What type of mystruct.mymember?
我應該如何保存N? 什么類型的mystruct.mymember? 我不知道它在h文件中。
你的解決方案
“如果std::_Array_iterator<_Ty,_Size>::difference_type
和ptrdiff_t
是不同的類型怎么辦?” 不要使用這樣的編譯器。 此外,它可能無法正式區別。 例如,使用默認標准分配器的vector
就是這種情況,因為它是獲取其typedef的地方,但由於正式保證無關緊要(他,他真的沒有)我不打算查看這個在C ++ 0x草案中。
所以,使用ptrdiff_t
。
但添加一些typedef是個好主意,比如
typedef ptrdiff_t Size;
typedef ptrdiff_t Index;
然后在您的具體案例中,您將使用Index
。
這些typedef自然伴隨着自定義的獨立countOf
, startOf
和endOf
函數,使您能夠以完全相同的方式處理原始數組和標准庫容器。
當你看到名稱Index
它更清楚一點,它是一個索引,無論你做什么,它都不能很自然地脫離Index
或Size
類型。 例如,添加一些東西,它仍然是一個Index
。 所以大多數情況下不會有“另外十幾個警告”。
但是在一些罕見的情況下,你需要從Index
到只有int
,比方說。 在極少數情況下,只需執行static_cast
即可關閉編譯器並明確您的意圖。 或者甚至是一個自定義的static_cast
like narrowTo
操作,用於表達......
干杯&hth。,
要保持max_element() - cont.begin()的結果,你應該使用
struct Foo { std::vector<int>::difference_type n; };
要么
template<typename T> struct Foo { std::vector<T>::difference_type n; };
要么
template<T> struct Foo { T n; };
因為difference_type是difference_type,並且當您將其強制轉換為int時,您將獲得未定義的行為。
您可以使用&* c.begin()將迭代器轉換為指針,並使用ptrdiff_t來表示此指針的差異。
我使用std::ptrdiff_t
。
我想不出一個合理的實現,其中std::vector<T>::iterator::difference_type
不能分配給std::ptrdiff_t
。 他們幾乎肯定會是一樣的。 如果它們不相同,則difference_type
必須小於ptrdiff_t
。
另外, ptrdiff_t
是一個帶符號的類型,所以如果你的所有代碼都設計為使用int
,你會比嘗試使用無符號類型更好,比如std::vector<int>::size_type
。
在visual-studio-2010
您可以編寫:
const auto N = std::max_element( cont.begin(), cont.end() ) - cont.begin();
我的解決方案是使用已知足夠大的類型,基於我所擁有的領域知識,但編譯器可能無法使用。 如果編譯器然后抱怨可能丟失數據,我添加一個強制轉換(這是保證安全的,因為我事先知道目標類型必須足夠大)。
使用std::vector<int>::size_type
:
difference_type
任何非負值 cont
非空,則std::max_element(cont.begin(), cont.end()) - cont.begin();
不會評估為負值。 如果它是空的,那么你不應該做任何這樣的處理。 那么這個'未知'類型我該怎么辦? 那時我會再收到十幾個警告。 我想用N做很多操作:保存,加法,乘法,循環等。
如果您始終使用該類型並將使用限制在實際需要的位置,則不會收到任何警告。 N
是向量的索引; 這就是它的好處。 您對其執行的任何有意義的操作都將導致另一個可能的向量索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.