2012-12-18 56 views
10

我怎麼能進行傳統陣列std::find無需對現有的傳統陣列作出新的std::vector/std::array上?的std ::找到了傳統陣列

例如:

int ar[N]; 

if (std::find(ar, ar + N, value) != &ar[N]){ /**/ } 

&ar[N]爲當什麼也沒發現檢查的情況有效的價值?我可以確定我正在使用&ar[N],就像std::vector::end()的模擬一樣嗎?

回答

19

如果使用C++ 11,可以使用:

int arr[N]; 
if (std::end(arr) == std::find(std::begin(arr), std::end(arr), value)) 
{ 
    // ... 
} 

對於C++ 98,可以使用:

int arr[N]; 
int *begin = arr; 
int *end = begin + N; 

if (end == std::find(begin, end, value)) 
{ 
    // ... 
} 
+3

編寫自己的'std :: begin'和'std :: end'版本並不難。 –

+0

@BenVoigt,我已經更新了代碼。 – utnapistim

+0

加上標註評論,也提升了開始和結束。 – 111111

2

是& ar [N]是一個有效的值,用於在沒有發現任何東西時檢查情況嗎?

可以使用ar+N代替&ar[N],因爲ar +N是安全的,但&ar[N]陷入未定義行爲的區域(有超過其實經過長時間的辯論)。

從語義上說,第二個參數是範圍實際上,所以當沒有範圍內發現任何你傳遞的第二個參數被返回。在你的情況下,ar + N是第二個參數,這也表示結束的範圍。所以你可以這樣寫:

if (std::find(ar, ar + N, value) != (ar + N)) 
{ 
     //value found 
} 
+1

你確定'&ar [N]'是合法嗎?它不涉及解引用? –

+0

@LuchianGrigore:這是一場漫長的辯論,但通常的結論是贊成的。 – Nawaz

+1

指針的特殊語言允許元素末尾的地址有意義。沒有爲引用啓用這種特殊行爲,'ar [N]'在任何評估的上下文中產生未定義的行爲,包括'&ar [N]'。 –

3

你的一般想法很好。但ar[N]不是「保留」給你。取消引用未分配的變量將導致未定義的行爲。你想比較std::find結果與ar + N,這不涉及解引用。

+1

你的第一句話是「你的解決方案很好。」但是你說它實際上並不好。哪一個? –

+0

檢查ar [N]的地址確實是一個很好的解決方案。但是,他不需要解除引用。對不起,如果我沒有讓自己清楚。 – tomahh

+0

你的意思是「你的解決方案很好」。他的解決方案涉及'&ar [N]',這顯然不好。另外「重新分配未分配的變量可能會導致未定義的行爲。」意味着有些情況下它不會導致UB,這又是錯誤的。 –

2

否,ar[N]解引用結束後一個元件數組,所以它是非法的。

記住ar[N]相當於*(ar + N) - 所以這顯然是一個間接引用。

改爲使用ar + N。在數組結尾後有一個指針1是合法的,取消引用它是非法的。