2013-06-19 29 views
9

要搜索一個元件第一次出現的在C-陣列與POD元件,一個易於可以與std::find_if(begin, end, findit)做到這一點。但我需要最後的發生。 This answer給了我這個想法,這可以用std::reverse_iterator完成。因此,我想:你如何在C風格的數組上使用find_if和reverse_iterator?

std::find_if(std::reverse_iterator<podtype*>(end), 
      std::reverse_iterator<podtype*>(begin), 
      findit); 

這給我的錯誤:

cannot convert 'std::reverse_iterator< xyz* > ' to 'xyz*' in assignment

你有一個想法如何做這種方式或者你知道一個更好的解決方案?

這是代碼:

#include <iostream> 
#include <iterator> 
#include <algorithm> 

struct xyz { 
    int a; 
    int b; 
}; 

bool findit(const xyz& a) { 
    return (a.a == 2 && a.b == 3); 
} 

int main() { 
    xyz begin[] = { {1, 2}, {2, 3}, {2, 3}, {3, 5} }; 
    xyz* end = begin + 4; 

    // Forward find 
    xyz* found = std::find_if(begin, end, findit); 
    if (found != end) 
     std::cout << "Found at position " 
        << found - begin 
        << std::endl; 

    // Reverse find 
    found = std::find_if(std::reverse_iterator<xyz*>(end), 
         std::reverse_iterator<xyz*>(begin), 
         findit); 
    if (found != std::reverse_iterator<xyz*>(end)); 
     std::cout << "Found at position " 
        << found - std::reverse_iterator<xyz*>(end) 
        << std::endl; 

    return 0; 
} 

compiler error on codepad.org

回答

11

std::find_if函數具有一個返回類型等於傳遞作爲參數的迭代器的類型。在你的情況下,由於你傳遞的是std::reverse_iterator<xyz*> s作爲參數,返回類型將是std::reverse_iterator<xyz*>。這意味着,

found = std::find_if(std::reverse_iterator<xyz*>(end), 
        std::reverse_iterator<xyz*>(begin), 
        findit); 

不會編譯,因爲foundxyz*

爲了解決這個問題,你可以試試這個:

std::reverse_iterator<xyz*> 
rfound = std::find_if(std::reverse_iterator<xyz*>(end), 
         std::reverse_iterator<xyz*>(begin), 
         findit); 

這將解決編譯錯誤。但是,我認爲,在這條線,你兩個次級錯誤:

if (found != std::reverse_iterator<xyz*>(end)); 

首先,請注意,你有if語句後一個分號,所以if語句體將被評估不管條件是否爲真。

其次,注意std::find_if返回第二個迭代器作爲前哨,如果沒有謂語一致。因此,這個測試應該是

if (rfound != std::reverse_iterator<xyz*>(begin)) 

因爲find_if將返回std::reverse_iterator<xyz*>(begin)如果沒有找到的元素。

希望這有助於!

+0

是的,這有助於,謝謝。在兩種情況下,返回的索引現在都是1,這看起來是正確的,但如果反向查找的結果會給出索引2,那麼返回索引將會很好。我不能從'rfound'中減去'begin',因爲這會導致與以前相同的錯誤。 –

+0

@ ChristianAmmer-我認爲這是因爲你的邏輯得到索引是錯誤的。你的減法計算從反向迭代器到數組最後一個元素的距離,它給出了距離數組後部*的距離*,而不是距離前面的距離。 – templatetypedef

+0

我想我現在明白了。邏輯錯了,但用'(end - begin) - (rfound - std :: reverse_iterator (end)) - 1'我得到正確的索引。 –