簡體   English   中英

我應該使用什么類型的迭代器差異來消除“可能的數據丟失”警告?

[英]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

我想通過共同的規則來解決這些問題。 哪種方式更好?

  1. 制作static_cast

     const int N = static_cast<int>( std::max_element(cont.begin(), cont.end()) - cont.begin() ); 

    我認為這不是通用的。 還有太多的信件。

  2. ptrdiff_t替換輸出類型:

     const ptrdiff_t N = std::max_element(cont.begin(), cont.end()) - cont.begin(); 

    那么這個未知類型ptrdiff_t應該怎么做? 那時我會再收到十幾個警告。 我想用N做很多操作:保存,加法,乘法,循環等等。 重要的是:但是如果std::_Array_iterator<_Ty,_Size>::difference_typeptrdiff_t是不同的類型怎么辦?

  3. 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文件中。

  4. 你的解決方案

“如果std::_Array_iterator<_Ty,_Size>::difference_typeptrdiff_t是不同的類型怎么辦?” 不要使用這樣的編譯器。 此外,它可能無法正式區別。 例如,使用默認標准分配器的vector就是這種情況,因為它是獲取其typedef的地方,但由於正式保證無關緊要(他,他真的沒有)我不打算查看這個在C ++ 0x草案中。

所以,使用ptrdiff_t

但添加一些typedef是個好主意,比如

typedef ptrdiff_t Size;
typedef ptrdiff_t Index;

然后在您的具體案例中,您將使用Index

這些typedef自然伴隨着自定義的獨立countOfstartOfendOf函數,使您能夠以完全相同的方式處理原始數組和標准庫容器。

當你看到名稱Index它更清楚一點,它是一個索引,無論你做什么,它都不能很自然地脫離IndexSize類型。 例如,添加一些東西,它仍然是一個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任何非負值
  • 這就是所有vector的索引操作都接受的
  • 如果cont非空,則std::max_element(cont.begin(), cont.end()) - cont.begin(); 不會評估為負值。 如果它是空的,那么你不應該做任何這樣的處理。

那么這個'未知'類型我該怎么辦? 那時我會再收到十幾個警告。 我想用N做很多操作:保存,加法,乘法,循環等。

如果您始終使用該類型並將使用限制在實際需要的位置,則不會收到任何警告。 N是向量的索引; 這就是它的好處。 您對其執行的任何有意義的操作都將導致另一個可能的向量索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM