In std::sort Funktor auf andere Klassen zugreifen?
-
Hallo,
angenommen ich habe folgendes Szenario:
class Money { public: int value; Money(int value_) : value(value_) {}; }; struct MoneyComparator { bool operator()(Money const &first, Money const &second) const { return first.value < second.value; // Hier würde ich gerne random_money aufrufen um es in den Vergleich mit einzubeziehen } }; class MoneyBag { public: MoneyBag(std::vector<Money> much_money_) : much_money(much_money_) {}; void sort_money() { std::sort(much_money.begin(), much_money.end(), MoneyComparator()); }; std::vector<Money> much_money; private: int random_money() { return 1; }; // Vereinfacht }; int _tmain(int argc, _TCHAR* argv[]) { MoneyBag my_money_bag(std::vector<Money>{5, 3, 8, 1, 2, 4}); my_money_bag.sort_money(); // Hier soll sortiert werden }Wie löse ich das dann am besten? Also ich hab quasi eine Klasse Geldbeutel die einen std::vector<Geld> enthält. Dieser vector soll sortiert werden. Allerdings will ich in der Sortiermethode auch noch auf eine Funktion der Geldbeutel-Klasse zugreifen (random_money), welche mir dort aber nicht zur Verfügung steht...
-
Gib
MoneyComparatoreinen Konstruktor, dem Du eine Referenz auf deinMoneyBagmitgibst.
-
Ok, also ich habs jetzt so probiert und der Compiler meckert von wegen Verwendung des undefinierten Typs "MoneyBag", wohl wegen der Vorwärtsdeklaration. Dabei verwende ich doch schon einen Pointer in der Sortier-Methode?
class Money { public: int value; Money(int value_) : value(value_) {}; }; class MoneyBag; struct MoneyComparator { MoneyComparator(MoneyBag *container_) : container(container_) {}; bool operator()(Money const &first, Money const &second) const { return first.value + container->random_money() < second.value + container->random_money(); } MoneyBag *container; }; class MoneyBag { public: MoneyBag(std::vector<Money> much_money_) : much_money(much_money_) {}; void sort_money() { std::sort(much_money.begin(), much_money.end(), MoneyComparator(this)); }; std::vector<Money> much_money; int random_money() { return 1; }; // Vereinfacht };
-
Hilft es, die Definition von
bool MoneyComparator::operator()()unter die Definition vonclass MoneyBag{}zu ziehen?
-
Tasächlich, damit klappt es dann

Auch wenn ich nicht verstehe warum... die Methode ist doch jetzt unter allen anderen Deklariert, wie das helfen kann kapier ich nicht
-
happystudent schrieb:
... die Methode ist doch jetzt unter allen anderen
DeklariertDefiniert
Sie benutzt die Methode
MoneyBag::random_money(), und die war an der alten Stelle noch nicht bekannt(nur eine Forwärtsdeklaration vonclass MoneyBag, keine Details)
-
Wie wäre es einfach mit einem Lambda?
-
Erzähl mal was das für einen Sinn machen soll also der Use Case
Muss ja was völlig verquertes sein
-
Wenn random_money einen zufälligen Wert zurückgeben sollte ist das btw. nicht erlaubt es im Comparotor-Objekt zu verwenden da es dann keine Ordnungsrelation mehr ist.
-
Ethon schrieb:
Wenn random_money einen zufälligen Wert zurückgeben sollte ist das btw. nicht erlaubt es im Comparotor-Objekt zu verwenden da es dann keine Ordnungsrelation mehr ist.
Ja das stimmt, war jetzt nicht das beste Beispiel mit dem random Wert. In echt wird hier kein random Wert verwendet, sondern ein deterministischer, mir ist nur für das Minimal-Beispiel nichts besseres eingefallen

......, schrieb:
Erzähl mal was das für einen Sinn machen soll also der Use Case
Muss ja was völlig verquertes seinIst für ein physikalisches System, dessen interne Zustände sortiert werden müssen...
Moneyist in Wirklichkeit sowas wiePhysicalStateund Moneybag istPhysicalSystem. Die States werden aber durch Veränderung ihrer Reihenfolge auch durch dasPhysicalSystembeeinflusst, daher will ich in der Sortiermethode auf Methoden vonPhysicalSystemzugreifen können.Arcoth schrieb:
Wie wäre es einfach mit einem Lambda?
Hm, aber wie soll ich das in den
operator()reinkriegen? Diestd::sortFunktion braucht ja einenoperator()der genau zwei Typen der zu vergleichenden Objekte nimmt?Caligulaminus schrieb:
Definiert
Sie benutzt die Methode
MoneyBag::random_money(), und die war an der alten Stelle noch nicht bekannt(nur eine Forwärtsdeklaration vonclass MoneyBag, keine Details)Hm Ok. Das ist schon sehr nervig muss ich sagen, aber gut. Kann man nicht irgendwie nur die Methode
MoneyBag::random_money()vorwärts-deklarieren?
-
happystudent schrieb:
Arcoth schrieb:
Wie wäre es einfach mit einem Lambda?
Hm, aber wie soll ich das in den
operator()reinkriegen? Diestd::sortFunktion braucht ja einenoperator()der genau zwei Typen der zu vergleichenden Objekte nimmt?Einfach hinschreiben. Lambdas sind genau für sowas da.
MoneyBag mb; std::sort(much_money.begin(), much_money.end(), [&](const Money &lhs, const Money &rhs){return mb.compare(lhs.value, rhs.value);} };
-
Hm, das ist natürlich nicht schlecht... werd ich gleich mal ausprobieren, danke
