Einfachster Weg bei einen Vektor out of range Null zurückzugeben



  • Hallo,

    angenommen ich habe folgenden Code:

    std::vector<int> testVector;
    testVector.push_back(1);
    testVector.push_back(2);
    testVector.push_back(3);
    testVector.push_back(4);
    testVector.push_back(5);
    int test = 0, back_horizont = 3;
    
    for (std::vector<int>::iterator i = testVector.begin(), e = testVector.end(); i != e; ++i) {
    	int temp = 0;
    
    	for (int k = 0; k < back_horizont; k++) {
    		temp += *(i - k);
    	}
    
    	test *= temp;
    }
    

    Dann gibt das ja ein Debug Assertion Failed, da in der inneren for-Schleife der range des Vektors verlassen wird.

    Ich hätte jetzt gerne eine kurze und elegante Methode um in so einem Fall dem Wert einfach 0 zuzuweisen - Also wenn *(i - k) out of range ist soll dort einfach Null addiert werden.

    Ich könnte in der aäußeren Schleife natürlich eine counter Variable mitschleppen und dann jeweils checken ob i - k noch in der gültigen range liegt, aber ich frage mich ob es eine einfachere/elegantere Lösung gibt?



  • ein iterator I ist in range wenn gilt begin()<=I<end()

    das lässt sich ja auch ohne extra variable easy checken.


  • Mod

    int k_max = std::min<int>(back_horizont, std::distance(testVector.begin(), i) + 1);
        for (int k = 0; k != k_max; ++k)
            temp += i[-k];
    

    (ungetestet)


  • Mod

    Das geht sogar viel kürzer:

    temp += std::accumulate( i - std::min<int>(back_horizont - 1, i - testVector.begin()), i + 1, 0 );
    // bzw.
    auto backward = std::min<int>(back_horizont - 1, i - testVector.begin());
    temp += std::accumulate( i - backward, i + 1, 0 );
    

    Ebenfalls ungetestet



  • Shade Of Mine schrieb:

    ein iterator I ist in range wenn gilt begin()<=I<end()

    das lässt sich ja auch ohne extra variable easy checken.

    Hm, ich hab immer i - k >= testVector.begin() getestet, was dann gecrashed ist. Mit i >= testVector.begin() + k dagegen funktioniert es.

    Arcoth schrieb:

    int k_max = std::min<int>(back_horizont, std::distance(testVector.begin(), i) + 1);
        for (int k = 0; k != k_max; ++k)
            temp += i[-k];
    

    (ungetestet)

    Dank, werd ich mir auch mal anschauen.



  • [quote="happystudent"]

    Shade Of Mine schrieb:

    Hm, ich hab immer i - k >= testVector.begin() getestet, was dann gecrashed ist.

    Ziemlich sicher benutzt der Vergleich size_t, was unsigned ist, sodass i - k sehr groß statt negativ wird.
    i >= testVector.begin() + k hat dieses Problem nicht.



  • Es reicht auch schon, wenn die Subtraktion zu einem Iterator führt, der ausserhalb des Intervalls [ begin(), end() [ liegt. Jeder Iterator vor begin() ist ungültig und allein dessen Erzeugung führt zu undefiniertem Verhalten.


Anmelden zum Antworten