Sortier-Problem



  • DANKE*DANKE*DANKE!

    ich hoffe, das klappt nachher, wenn ich es zu Hause implementiere.
    Aber ich verstehe, was da gemacht wird, und jetzt verstehe ich auch den Sinn, den mir die MSDN (mir etwas zu abstrakt) vermittlen will..

    Falk.



  • So, ich habs jetzt zu Hause versucht, ABER:

    er gibt mir folgenden Fehler, den ich nicht deuten kann:

    error C2664: 'void __thiscall std::list<struct element,class std::allocator<struct element> >::sort(struct std::greater<struct element>)' : cannot convert parameter 1 from 'struct ElementProfitGewichtSorter' to 'struct std::greater<struct element>'
            No constructor could take the source type, or constructor overload resolution was ambiguous
    

    Was bedeutet das? (Was mache ich noch falsch?)

    Der Fehler erscheint bei folgendem kleinen Programm:

    #include <list> 
    using namespace std; 
    
    struct element
    {
      	float gewicht;
    	float profit;
    };
    
    struct ElementProfitGewichtSorter
    {
    public:
      bool operator()(const element &e1, const element &e2) const
      {
        return (e1.profit / e1.gewicht) < (e2.profit / e2.gewicht);
      }
    };
    
    typedef list<element> listElemente;
    
    void main()
    {
       listElemente lst;
    
       lst.sort(ElementProfitGewichtSorter()); // <<--- HIER DER FEHLER !!!
    }
    

    Falk.



  • ichfalk schrieb:

    error C2664: 'void __thiscall std::list<struct element,class std::allocator<struct element> >::sort(struct std::greater<struct element>)' : cannot convert parameter 1 from 'struct ElementProfitGewichtSorter' to 'struct std::greater<struct element>'
            No constructor could take the source type, or constructor overload resolution was ambiguous
    

    Was bedeutet das? (Was mache ich noch falsch?)

    Du verwendest MS Visual C++ 6 mit der mitgelieferten STL.
    Nimm einen anderen Compiler oder eine andere STL (z.B. STLPort).



  • Aha, und wo stelle ich sowas wie STLPort ein?
    In der MSDN hab ich nix gefunden...
    Falk.



  • Schau mal bei stlport.org vorbei.
    Diese STL läuft auch mit VC6, allerdings kann deren list::sort mit beliebigen Prädikaten umgehen. Warum das in der mitgelieferten STL nicht auch geht, ist mir bis heute ein Rätsel.



  • tag schrieb:

    Warum das in der mitgelieferten STL nicht auch geht, ist mir bis heute ein Rätsel.

    Ganz einfach. Die mitgelieferte STL wurde für ältere Versionen des VCs entwickelt und die beherrschten noch keine Member-Templates.
    Hier musst du deshalb std::greater spezialisieren.



  • HumeSikkins schrieb:

    Hier musst du deshalb std::greater spezialisieren.

    explicit specialization von std::greater hilft ihm nicht, weil er einmal über (profit/gewicht) und ein andermal nur über (gewicht) sortieren will.

    //edit
    kann ihm sowas helfen?

    //mySort.h

    void sortMyListByProfitGewicht(std::list<MyStruct> &lst);
    void sortMyListByGewicht(std::list<MyStruct> &lst);
    

    //mySortProfitGewicht.cpp

    template<>
    struct std::greater<MyStruct>
    {
    //...
    };
    
    void sortMyListByProfitGewicht(std::list<MyStruct> &lst)
    {
      lst.sort();
    }
    

    //mySortGewicht.cpp

    template<>
    struct std::greater<MyStruct>
    {
    //...
    };
    
    void sortMyListByGewicht(std::list<MyStruct> &lst)
    {
      lst.sort();
    }
    

    😃



  • ssm schrieb:

    HumeSikkins schrieb:

    Hier musst du deshalb std::greater spezialisieren.

    explicit specialization von std::greater hilft ihm nicht, weil er einmal über (profit/gewicht) und ein andermal nur über (gewicht) sortieren will.

    Das "hier" bezog sich auf "Compiler die keine Member-Templates unterstützen" nicht auf "die hier gegebene Situation".

    Btw:

    struct element
    {
          float gewicht;
        float profit;
    enum CmpBy{a, b, c};
    };
    
    namespace std
    {
         template <>
         struct greater< ::element>
         {
             greater(::element::CmpBy sc)
                  : sc_(sc)
             {}
             bool operator()(const ::element& lhs, const ::element& rhs) const
             {
                  switch(sc_)
                  {
                  case ::element::a: return compareByA(lhs, rhs);
                  case ::element::b: return compareByB(lhs, rhs);
                  ...
                  }
             }
        private:
            bool compareByA(const ::element& lhs, const ::element& rhs) const;
            ...
            ::element::CmpBy sc_;
    
         };
    }
    ...
    list<element> l;
    l.sort(greater<element>(element::a));
    

    Nicht schön, aber immerhin eine Lösung.



  • ssm schrieb:

    kann ihm sowas helfen?

    Nur wenn er der Meinung ist, dass undefiniertes Verhalten hilfreich ist.
    Aus Sicht von Standard-C++ ist die Antwort nein. Du verletzte die ODR, rufst dadurch undefiniertes Verhalten hervor und eröffnest damit grünen Nasenkobolden die Möglichkeit aus deiner Nase zu fliegen 😃



  • HumeSikkins schrieb:

    Nur wenn er der Meinung ist, dass undefiniertes Verhalten hilfreich ist.

    😃



  • Danke Euch allen!

    Das mit der STLPort hat super geklappt!

    Falk.



  • HumeSikkins schrieb:

    [quellcode]
    Nicht schön, aber immerhin eine Lösung.

    Aber die Idee ist an sich nicht schlecht. Werde ich mir mal merken 😉


Anmelden zum Antworten