Kann list vom typ struct nicht Sortieren, wenn struct private ist...



  • Ich bin leider zu unerfahren, um dieses Problem ohne Hilfe zu lösen.

    Folgender Quellcode funktioniert tadellos:

    #include <list>
    #include <iostream>
    
    using namespace std;
    class ctest
    {
    	public:
    					ctest() {};
    					void createdata();
    					void sortdata();
    					void printdata();
    					~ctest();
    
    					struct strresulttwo
    					{
    						int e;
    						int x1;
    						int x2;
    					} tresulttwo;
    
    	private:
    					list<strresulttwo> fieldresult;
    					list<strresulttwo>::iterator ifieldresult;
    };
    
    template<> 
    bool std::greater<ctest::strresulttwo>::operator()(ctest::strresulttwo const& lhs,ctest::strresulttwo const& rhs) const
    { 
    	return lhs.e < rhs.e;  
    }
    
    ctest::~ctest()
    {
    	fieldresult.clear();
    }
    
    void ctest::createdata()
    {
    	for(int i=0; i<=10; i++)
    	{
    		tresulttwo.x1=(rand()%10);
    		tresulttwo.x2=(rand()%10);
    		tresulttwo.e=tresulttwo.x1+tresulttwo.x2;
    		fieldresult.push_back(tresulttwo);
    	}
    }
    
    void ctest::sortdata()
    {
    	fieldresult.sort(std::greater<strresulttwo>());
    }
    
    void ctest::printdata()
    {
    	for(ifieldresult=fieldresult.begin(); ifieldresult!=fieldresult.end(); ifieldresult++)
    		cout << ifieldresult->x1 << "+" << ifieldresult->x2 << "=" << ifieldresult->e << "\n";
    }
    
    int main()
    {
    	ctest test;
    	test.createdata();
    	test.sortdata();
    	test.printdata();
    	return 0;
    }
    

    Wenn ich aber das Struct in private nehme, wie hier:

    class ctest
    {
    	public:
    					ctest() {};
    					void createdata();
    					void sortdata();
    					void printdata();
    					~ctest();
    
    	private:
    					struct strresulttwo
    					{
    						int e;
    						int x1;
    						int x2;
    					} tresulttwo;
    					list<strresulttwo> fieldresult;
    					list<strresulttwo>::iterator ifieldresult;
    
    };
    

    Dann bringt mein Compiler natürlich die Fehlermeldung:

    In member function 'bool std::greater<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = ctest::strresulttwo}':
    error:'struct ctest::strresulttwo' is private
    error: within this context
    error:'struct ctest::strresulttwo' is private
    error: within this context
    error:'struct ctest::strresulttwo' is private
    error: within this context
    

    Ich hab schon die Suchmaschine bemüht, aber nichts gefunden was mein Problem betrifft. Danke.



  • template<>
    bool std::greater<ctest::strresulttwo>::operator()(ctest::strresulttwo const& lhs,ctest::strresulttwo const& rhs) const
    {
        return lhs.e < rhs.e;  
    }
    

    Und du erwartest ernsthaft das das ganze noch funktioniert nachdem du strresulttwo
    private gemacht hast ?? Wie soll die Funktion denn darauf zugreifen 😕



  • Dann bringt mein Compiler natürlich die Fehlermeldung:

    Noch Fragen? 🙂

    Ich weiß dass es nicht mehr klappt, wenn ich struct in private nimm. Ich möchte wissen, wie ich greater anpassen muss, damit ich das struct in private nehmen kann. Wenn man es in diesem Fall überhaupt anpassen kann.
    Vom logischen her, würd ich greater in meine Klasse aufnehmen. Aber ich hab absolut keine Ahnung wie ich dass machen soll, wenn es denn überhaupt in dieser Richtung gehen würde.



  • Kennst du das Schlüsselwort fiend? (Nur mal so ins blaue, hab keine Zeit den Quellcode anzugucken)



  • [cpp]#include <list>
    #include <iostream>

    using namespace std;
    class ctest
    {
    public:
    ctest() {};
    void createdata();
    void sortdata();
    void printdata();
    ~ctest();

    struct strresulttwo
    {
    int e;
    int x1;
    int x2;

    bool operator<(strresulttwo const& rhs) const
    {
    return e < rhs.e;
    }

    } tresulttwo;

    private:
    list<strresulttwo> fieldresult;
    list<strresulttwo>::iterator ifieldresult;
    };

    ctest::~ctest()
    {
    fieldresult.clear();
    }

    void ctest::createdata()
    {
    for(int i=0; i<=10; i++)
    {
    tresulttwo.x1=(rand()%10);
    tresulttwo.x2=(rand()%10);
    tresulttwo.e=tresulttwo.x1+tresulttwo.x2;
    fieldresult.push_back(tresulttwo);
    }
    }

    void ctest::sortdata()
    {
    fieldresult.sort();
    }

    void ctest::printdata()
    {
    for(ifieldresult=fieldresult.begin(); ifieldresult!=fieldresult.end(); ifieldresult++)
    cout << ifieldresult->x1 << "+" << ifieldresult->x2 << "=" << ifieldresult->e << "\n";
    }

    int main()
    {
    ctest test;
    test.createdata();
    test.sortdata();
    test.printdata();
    return 0;
    }[/cpp]



  • Danke, der Code funktioniert. Jetzt hab ich das Problem, dass ich einmal aufsteigend und einmal absteigend sortieren will. Ich hab schon ein paar Sachen ausprobiert, aber ich komme einfach nicht auf einen grünen Zweig.
    Ich hab schon was von greater und less gehört, aber ich weiß nicht wie ich das anwenden soll.



  • Es war doch deine grosse Anforderung das die struct private sein sollte.
    Und jetzt gehts ganz plötzlich auch ohne 😕 😕



  • Also manchmal wünschte ich mir, dass sinnlose Kommentare in diesem Forum unterbleiben würden. 😡
    ssm hats einfach nur versäumt das struct in private zu stecken. Ich hab den Code mit struct in private ausprobiert und es funktioniert.



  • Oh Mann, wie einfach:

    void ctest::sortdata() 
    { 
          fieldresult.sort();    
          fieldresult.reverse(); 
    }
    

    Damit wird das sortierte Ergebnis einfach umgedreht.

    Sorry für obiges Kommentar 🙄



  • wobei, wenn du fuer nen absteigendes sortieren immer sort, dann reverse aufrufen wuerdes, im einsatz fuer ernsthafte Software, also kein prototyp, ... wuerde ich dir als proj. Manager die Haende abhacken 🙂

    schau dir wirklich mal die STL genauer an, und wie man die sortierfunktion da definieren kann ....obwohl das ja so falsch ned war im 1. ansatz.

    also in deinem speziellen fall, arbeite mit friend, oder ueberarbeite dein Design ...
    wie waers zum besipiel, wenn due dein funktiosobject (greater) auch private machst ? waer auch logisch, weil nur wer die structur kennt, brauch auch ne funktion zum vergleich ... diese brauch dann auch nimmer generisch zu sein ...
    Warum du das unbedingt mit nem template machen willst ..... ???

    Ciao ...



  • Ich hab schon stundenlang versucht das funktiosobject (greater) auch private zu machen, aber ich bekam meistens Fehler bezüglich falschem Namespace. Wo kann ich mir das Wissen dafür aneignen? Bzw. in welche Richtung von C++ geht das Überhaupt?
    Ich muss das nicht unbedingt mit einem template machen, aber für einen schnellen Erfolg fühlte ich mich da am sichersten.



  • 😡

    Variant 1

    struct strresulttwo 
    { 
    	int e; 
    	int x1; 
    	int x2; 
    
    	bool operator<(const strresulttwo &str) const
    	{
    		return e < str.e;
    	}
    
    	bool operator>(const strresulttwo &str) const
    	{
    		return e > str.e;
    	}
    }; 
    
    //...
    std::list<strresulttwo> l;
    
    //asc
    l.sort(std::less<strresulttwo>());
    
    //desc
    l.sort(std::greater<strresulttwo>());
    

    Variant 2

    struct strresulttwo 
    { 
    	int e; 
    	int x1; 
    	int x2; 
    }; 
    
    //...
    
    template<
    	template <class FParam> class F, //binary functor
    	typename T,						//struct type
    	typename U>						//field type	
    class Struct2fieldImpl
    {
    public:	
    	Struct2fieldImpl(U T::*pField) 
    		: pField(pField)
    	{
    	}
    
    	bool operator()(const T &l, const T &r) const
    	{
    		return F<U>()(l.*pField, r.*pField);
    	}
    
    private:
    	U T::*pField;
    };
    
    template< 
    	template <class U> class F, //binary functor
    	typename T,					//struct type
    	typename U>					//field type	
    Struct2fieldImpl<F, T, U> struct2field(U T::*pField)
    {
    	return Struct2fieldImpl<F, T, U>(pField);
    }
    
    //...
    
    std::list<strresulttwo> l;
    
    //asc
    l.sort(struct2field<std::less>(&strresulttwo::e));	
    
    //desc
    l.sort(struct2field<std::greater>(&strresulttwo::e));
    

Anmelden zum Antworten