Wie macht man in C++ ein änderbares Void?

2 Antworten

Du meinst, du willst eine Funktion schreiben, die es dem Aufrufer erlauben soll, Teile des Verhaltens der Funktion zu manipulieren?

In C würde man dies über Funktionspointer lösen:

void repeat_10_times(void(*callback)(int)) {
    for(int i = 0; i < 10; i++)
        callback(i);
}

// ...

void function_to_repeat(int i) {
    // Do something with the value i
}

int main() {
    repeat_10_times(function_to_repeat);
    return 0;
}

In C++ gibt es außerdem std::function, was nicht nur einen Funktionspointer, sondern auch andere funktionsartige Objekte, wie beispielsweise Lambda-Ausdrücke entgegen nehmen kann:

#include <functional>

void call_ten_times(std::function<void(int)> callback) {
    for(int i = 0; i < 10; i++)
        callback(i);
}

// ...

int ten_factorial() {
    int result = 1;
    call_ten_times([&result](int i){ result *= i + 1 });
    return result;
}

int main() {
    std::cout << ten_factorial() << std::endl;
    return 0;
}
Woher ich das weiß:Berufserfahrung – Hauptberuflich IT-Consultant, Informatikstudium

welches void ist in den Beispielen veränderbar?

0
@BossWither

Änderbar ist keine Funktion wirklich. Aber du kannst Funktionspointer oder std::function nutzen, um zu verändern, was in call_ten_times bzw. repeat_10_times innerhalb der For-Schleife gemacht werden soll.

Hier ist übrigens noch eine weitere Möglichkeit, die Templates nutzt (und außerdem Concepts, ein C++20-Feature, mit dem du Einschränkungen für den Template-Parameter T festlegen kannst):

template<class C> concept addable = requires(const C& c, int i) {
    { c.add(i) } -> std::convertible_to<C>;
};

template<addable T> T add_0_through_9(T&& t) {
    T result{ t };
    for(int i = 0; i < 10; i++)
        result = result.add(i);
    return result;
}

// ...

struct int_test {
    const int value;

    int_test add(int i) const {
        return { value + i };
    }
};

struct string_test {
    const std::string value;

    string_test add(int i) const {
        return { value + i };
    }
};

int main() {
    std::cout << add_0_through_9(int_test{ 0 }).value << std::endl;
    std::cout << add_0_through_9(string_test{ "" }).value << std::endl;
    return 0;
}
0

Void ist in C++ ein Datentyp welcher eigentlich kein Typ ist.

Also was soll in diesem Kontext bitte "ein Void" bzw "ein normales Void" sein?

Wenn du einen Void Pointer meinst also void* so ist das zunächst mal schlechte Praxis in C++ und zum anderen kannst du die Daten hinter so einem Void Pointer logischerweise nicht verändern oder lesen.

mit normales void ist ein void gemeint welches nur aus: void IrgendeinVoidName() {code} besteht

0
@BossWither

Das nennt sich nicht Void sondern Funktion. Der Rückgabewert dieser Funktion ist void oder anders gesagt die Funktion liefert keinen Wert zurück.

Eine Funktion muss zur Compile Time vollständig definiert sein, somit kann man während der Ausführung die Funktion nicht direkt ändern. Es gibt zwar so etwas wie selbstmodifizierenden Code aber hier kann natürlich nicht der Quelltext verändert werden da dieser zur Laufzeit ja nicht mehr existiert.

Die einfachste Möglichkeit das Verhalten einer Funktion zur Laufzeit zu ändern wäre über Callbackfunktionen allerdings sollte man das aufgrund der Leserlichkeit so vermeiden.

0