Durch Funktion über Fortschritt informiert werden (z.B. Callback?)



  • Es existiert folgende Funktion, die für sich alleine stehend übersetzt und projektübergreifend genutzt werden kann:

    /* findSomething testet 255 Adressen auf Antwort und liefert einen Vektor
     * mit den verfügbaren Adressen zurück, z.B. 13,14,180,253.
    */
    std::vector<int> findSomething() {
    	for (int i = 0; i < 255; ++i) {
        // [...]
        }
    }
    

    Jetzt dauert das aber ein wenig, so dass es sich lohnt, bei einer GUI dem Anwender den Fortschritt mitzuteilen. Z.B. so:

    Teste Adresse 0... keine Antwort
    Teste Adresse 1... Antwort

    Oder ein Fortschrittsbalken (oder beides).

    Nur wie kann ich das realisieren, dass ich bei Bedarf Rückmeldung von der Funktion bekommen. Ein Ansatz war Folgender:

    std::vector<int> findSomething(void(*pFunc_TryingAddr)(int) = 0, void(*pFunc_FoundDevice)(int) = 0) {
    	for (int i = 0; i < 255; ++i) {
    		if (pFunc_TryingAddr) {
    			pFunc_TryingAddr(i);
    		}
            // [...]
    			if (bSuccess && pFunc_FoundDevice) {
    				pFunc_FoundDevice(i);
    			}
                // vec.push_back(i);
        }
    }
    

    Aber irgendwie fühlt sich das für mich nicht "optimal" an. Was wären eure Ideen? Oberstes Ziel ist, das die Suche komplett entkoppelt bleibt.



  • //Annahme: Die Ursprungsfunktion sieht ungefähr so aus
    std::vector<int> findSomething() {
    	std::vector<int> results;
    	for (int i = 0; i < 255; ++i) {
    		if (tryAddress(i)) {
    			results.push_back(i);
    		}
    	}
    	return results;
    }
    
    //Verallgemeinerung der Rückgabemethode:
    template <class AddressCallback>
    void findSomething2(AddressCallback handle_result) {
    	for (int i = 0; i < 255; ++i) {
    		if (tryAddress(i)) {
    			handle_result(i);
    		}
    	}
    }
    
    //eine Zusatzinformation über einen zweiten Callback
    template <class AddressCallback1, class AddressCallback2>
    void findSomething3(AddressCallback1 handle_result, AddressCallback2 handle_trying) {
    	for (int i = 0; i < 255; ++i) {
    		handle_trying(i);
    		if (tryAddress(i)) {
    			handle_result(i);
    		}
    	}
    }
    
    //das zweite Argument kann leicht optional gemacht werden
    template <class AddressCallback>
    void findSomething3(AddressCallback handle_result) {
    	findSomething3(handle_result, [](int) { /*ignore*/ });
    }
    
    int main()
    {
    	std::vector<int> results;
    	findSomething3(
    		[&results](int result)
    		{
    			results.push_back(result);
    		},
    		[](int trying)
    		{
    			//...
    		}
    	);
    }
    


  • Ok, mit deinem Beispiel sind jetzt auch Lambdas bei mir angekommen. Ich finde deine Lösung sehr elegant. Viel eleganter als meine. Und jetzt wo ich lambdas grob verstanden habe, kann mein Auge auch die Syntax erfassen 😃 🙂

    Dein Vorschlag wird so übernommen. Du hast mir sehr geholfen!


Log in to reply