[Erledigt] template fehler?



  • Hallo Leute,

    meine Klasse sieht so aus:

    // Siehe Nachtrag
    

    Sie hütet die vier container maps in dennen die ganze topologie steckt. Jetzt habe ich ein template geschrieben welches auf die get_... funktionen reagieren soll.

    // Siehe Nachtrag
    

    Und nun möchte ich die get Funktionen erstellen die so aussehen mögen:

    // Siehe Nachtrag
    

    Beim Kompilieren bekomme ich einen etwas unverständlichen Fehler in Zeile 42 des zweiten Codeschnippsels:

    error C2440: 'initializing' : cannot convert from 'std::_Tree_const_iterator<_Mytree>' to 'std::_Tree_const_iterator<_Mytree>'
    

    Was geht hier schief? Er muss doch nicht konvertieren?!

    Nachtrag:
    Hier ein funktionsfähiger Codeschnipsel das direkt ohne überstetzt werden kann:

    #include <map>
    
    using namespace std;
    
    typedef int Utm;
    typedef int Knot;
    typedef int Edge;
    typedef int Face;
    typedef unsigned int pano_uint;
    
    template<typename T> struct topology{
    
    	typedef typename pair<pano_uint,T> pair;
    	typedef typename map<pano_uint,T>::iterator it;
    	typedef typename map<pano_uint,T>::const_iterator const_it;
    	typedef std::pair<it,bool> bool_it;
    
    };
    
    class Geotopology{
    
    private:
    	template<typename T, typename S> pano_uint get_id_by_pos(T& container, S pos) const;
    
    	map<pano_uint, Utm> coords;
    	map<pano_uint, Knot> knots;
    	map<pano_uint, Edge> edges;
    	map<pano_uint, Face> faces;
    
    public:
    	int get_coord_by_pos(pano_uint pos_in_map) const;
    	int get_knot_by_pos(pano_uint pos_in_map) const;
    	int get_edge_by_pos(pano_uint pos_in_map) const;
    	int get_face_by_pos(pano_uint pos_in_map) const;
    };
    
    template<typename T, typename S> pano_uint Geotopology::get_id_by_pos(T& container, S pos) const{
    
    	typedef typename topology<T>::const_it const_iter_t;
    
    	const_iter_t i = container.begin();
    	std::advance(i, pos-1);
    
    	return i->first;
    } 
    
    int Geotopology::get_coord_by_pos(pano_uint pos_in_map) const{
    	return get_id_by_pos(coords,pos_in_map); 
    }
    
    int main(void){
    
    	return 0;
    
    }
    


  • Da steht noch mehr in der Fehlermeldung, du musst die komplette Ausgabe anschauen. Ich vermute, der Typ T ist nicht UTM .

    Warum eigentlich die topology -Klasse? Mach doch die Typedefs gleich in GEOTopology .

    Und dass du dir eine einheitliche Namenskonvention aneignen solltest, wurde auch schon mehrmals gesagt. Es hilft auch uns dabei, deinen Code zu verstehen. Für Typen verwendest du z.B. je nach Wetter eine der folgenden Schreibweisen, das solltest du unbedingt vereinheitlichen.

    ALLES_GROSS:     PANO_UINT
    alles_klein:     const_it
    HALBGross:       GEOTopology
    


  • Geht die Fehlermeldung nicht noch weiter?
    Ich bin auch grad zu blöd den Fehler zu finden. Aber wieso machst du das überhaupt so komisch?

    template<typename T, typename S> PANO_UINT GEOTopology::get_id_by_pos(T& container, S pos) const
    {
        typename T::const_iterator i = container.begin();
        std::advance(i, pos-1);
    
        return i->first;
    }
    

    Dass dieses ganze "id_by_pos" für ne map bischen blöd ist wurde dir ja schonmal gesagt.



  • Nexus schrieb:

    ...

    Das mit den Namenskonventionen habe ich schon längs akzeptiert :))
    Ich wehre mich in keinem Post gegen diese Verbesserungsvorschläge.
    Mit den Templates werden auch die letzten großen Bezeichner untergehen.

    brotbernd schrieb:

    ...

    Ich weiß es sieht ziemlich unglücklich aus. Die map bietet jedoch an vielen Stellen die man hier leider nicht sehen kann enorme Vorteile gegenüber vector usw..

    Die ganze Fehlermeldung:

    1>d:\desktop\panotest\panotest\panotest.cpp(41): error C2440: 'initializing' : cannot convert from 'std::_Tree_const_iterator<_Mytree>' to 'std::_Tree_const_iterator<_Mytree>'
    1>          with
    1>          [
    1>              _Mytree=std::_Tree_val<std::_Tmap_traits<PANO_UINT,UTM,std::less<PANO_UINT>,std::allocator<std::pair<const PANO_UINT,UTM>>,false>>
    1>          ]
    1>          and
    1>          [
    1>              _Mytree=std::_Tree_val<std::_Tmap_traits<PANO_UINT,const std::map<PANO_UINT,UTM>,std::less<PANO_UINT>,std::allocator<std::pair<const PANO_UINT,const std::map<PANO_UINT,UTM>>>,false>>
    1>          ]
    1>          No constructor could take the source type, or constructor overload resolution was ambiguous
    1>          d:\desktop\panotest\panotest\panotest.cpp(48) : see reference to function template instantiation 'PANO_UINT GEOTopology::get_id_by_pos<const std::map<_Kty,_Ty>,PANO_UINT>(T &,S) const' being compiled
    1>          with
    1>          [
    1>              _Kty=PANO_UINT,
    1>              _Ty=UTM,
    1>              T=const std::map<PANO_UINT,UTM>,
    1>              S=PANO_UINT
    1>          ]
    

    Der Kompiliervorgang wird danach abgebrochen.



  • Also hatte ich mit meiner Vermutung recht.

    T ist nicht UTM , sondern const std::map<PANO_UINT,UTM> . Für eine Iterator-Konvertierbarkeit müssen die beiden Value-Typen der Map aber gleich sein.



  • darkfate schrieb:

    brotbernd schrieb:

    ...

    Ich weiß es sieht ziemlich unglücklich aus. Die map bietet jedoch an vielen Stellen die man hier leider nicht sehen kann enorme Vorteile gegenüber vector usw..

    Ich hatte dir ja schonmal boost::multi_index_container vorgeschlagen. Da hast du beides in einem.



  • brotbernd schrieb:

    Ich hatte dir ja schonmal boost::multi_index_container vorgeschlagen. Da hast du beides in einem.

    Ich brauch einen Container der automatisch sortiert.
    Nur eindeutige Ids zulässt usw.



  • ja: boost::multi_index_container 😉



  • brotbernd schrieb:

    ja: boost::multi_index_container 😉

    Ich wehre mich ja nicht dagegen.
    Welche Vorteile hätte er gegenüber dem was ich an der map habe?



  • Nexus schrieb:

    Also hatte ich mit meiner Vermutung recht.

    T ist nicht UTM , sondern const std::map<PANO_UINT,UTM> . Für eine Iterator-Konvertierbarkeit müssen die beiden Value-Typen der Map aber gleich sein.

    Ja, jetzt sehe ich es auch.. danke für den Tipp.

    Nexus schrieb:

    Warum eigentlich die topology -Klasse? Mach doch die Typedefs gleich in GEOTopology .

    topology ist doch nur ein template struct?
    Könntest du mir zeigen wie du es meinst?



  • Dass du zusätzlich einen random access "Index" dazupacken kannst. Genauso wie beliebig viele weitere. Du kannst deine Daten z.B. mit 10 verschiedenen Vergleichsobjekten indiziert haben.
    Du kannst dann in etwa:

    container.get<byID>(3);
    container.get<byName>("hanswurst");
    container.get<byPos>(100);
    

    Ich hab jetzt die genaue Syntax nicht im Kopf, ist recht komplex das ganze Ding, aber sehr schick. Benutze ich z.B. wenn man in einer GUI sehr große Listen hat, die nach jeder Spalte sortiert werden können. Ist alles fertig sortiert und per random access abrufbar.



  • brotbernd schrieb:

    ja: boost::multi_index_container

    Warum nicht einfach ein std::vector , der fortlaufend sortiert ist? Man kann dann Werte in O(n) an der richtigen Stelle einfügen, und auf Duplikate kann man auch gleich prüfen. Leider hat man auch unnötige Kopien nach dem eingefügten Objekt. Kommt halt drauf an, ob Einfügungen im Vergleich zum Random Access selten vorkommen. Sonst wäre std::deque eine Zwischenlösung.

    Edit: Hab deinen letzten Post noch nicht gesehen. Wenn man natürlich nach unterschiedlichen Kriterien auslesen will, ist das schon nicht schlecht. Wobei ich die Effizienz und Zeitkomplexität von boost::multi_index nicht gerade im Kopf habe...

    darkfate schrieb:

    topology ist doch nur ein template struct?
    Könntest du mir zeigen wie du es meinst?

    Ich dachte einfach daran, die typedef s aus topology in Geotopology zu verschieben. Aber wahrscheinlich habe ich das zu eng gesehen, und du brauchst topology an mehreren Orten.



  • Nexus schrieb:

    Wobei ich die Effizienz und Zeitkomplexität von boost::multi_index nicht gerade im Kopf habe...

    Die ist je Index ganz grob vergleichbar mit dem entsprechenden STL Container.
    Als problematisch kann ich wenn nur die Kompilierzeiteffizienz ansehen. Wir hatten mal einen Container der alleine 5min kompiliert hat 😮
    Son Ding muss man dann schon gut verstecken, sonst wird man bekloppt.



  • Nexus schrieb:

    ...

    Meine Vorgaben sind:
    Koordinaten, Knoten, Kanten, Maschen: unique id, nach id sortiert;

    Jeder Knoten hat mind. 3 Koordinaten, die ihn referenzieren.
    Jede Kante zwei Knoten.
    Geschlossene Kanten bilden jeweils eine Masche.

    Die Funktionen get_xxxx_by_pos(x) nutze ich beim laden/speichern einer Projektdatei und bei der opengl Ausgabe in einer for Schleife.

    Vector hat keine unique ids soviel ich weiß.

    Lasse mich aber gerne beraten.

    Boost sieht zwar gut aus aber ich möchte so viel wie möglich in eigener Kontrolle haben.



  • darkfate schrieb:

    Die Funktionen get_xxxx_by_pos(x) nutze ich beim laden/speichern einer Projektdatei und bei der opengl Ausgabe in einer for Schleife.

    Also da Laden und Speichern ist wurst, das ist eh langsam. Aber für Grafikausgabe klingt das ganz schlimm. Ist denn deine for schleife von pos=0 bis x ?
    Dann iteriere doch einfach ganz normal durch die map.



  • brotbernd schrieb:

    darkfate schrieb:

    Die Funktionen get_xxxx_by_pos(x) nutze ich beim laden/speichern einer Projektdatei und bei der opengl Ausgabe in einer for Schleife.

    Also da Laden und Speichern ist wurst, das ist eh langsam. Aber für Grafikausgabe klingt das ganz schlimm. Ist denn deine for schleife von pos=0 bis x ?
    Dann iteriere doch einfach ganz normal durch die map.

    ja von pos=0 bis x. Ist aber nicht weiter wild.
    Funktioniert eigentlich ganz gut.

    Ich möchte diese Topologie Klasse geschlossen von der Applikation halten und nur externe Methoden anbieten über die man sie ansprechen kann. Am besten so einfach wie möglich, daher das get_xxx_by_xxx(x)



  • darkfate schrieb:

    ja von pos=0 bis x.

    Von vorne bis hinten durch ist ja kein random access. Dafür musst du ja nicht für jede Position wieder von vorne anfangen zu zählen ( std::advance(it,pos) )

    class Geotopology{
    
    public:
    	typedef std::map<pano_uint, Utm> coord_map;
    	typedef coord_map::const_iterator coord_iter;
    	typedef std::map<pano_uint, Knot> knots_map;
    	typedef coord_map::const_iterator knots_iter;
    
        coord_iter first_coord() const;
    	coord_iter last_coord() const;
    	knots_iter first_knot() const;
    	knots_iter last_knot() const;
    
    private:
        coord_map coords;
        knots_map knots;
    }; 
    
    int main()
    {
    	using namespace std;
    
    	Geotopology g;
    
    	for(Geotopology::knots_iter it = g.first_knot(),end = g.last_knot();
    		it != end; ++it)
    	{
    		glDraw(*it);
    	}
        // std::for_each(g.first_knot(), g.last_knot(), ...);
    	return 0;
    }
    


  • brotbernd schrieb:

    darkfate schrieb:

    ja von pos=0 bis x.

    Von vorne bis hinten durch ist ja kein random access. Dafür musst du ja nicht für jede Position wieder von vorne anfangen zu zählen ( std::advance(it,pos) )

    class Geotopology{
    
    public:
    	typedef std::map<pano_uint, Utm> coord_map;
    	typedef coord_map::const_iterator coord_iter;
    	typedef std::map<pano_uint, Knot> knots_map;
    	typedef coord_map::const_iterator knots_iter;
    
        coord_iter first_coord() const;
    	coord_iter last_coord() const;
    	knots_iter first_knot() const;
    	knots_iter last_knot() const;
    
    private:
        coord_map coords;
        knots_map knots;
    }; 
    
    int main()
    {
    	using namespace std;
    
    	Geotopology g;
    
    	for(Geotopology::knots_iter it = g.first_knot(),end = g.last_knot();
    		it != end; ++it)
    	{
    		glDraw(*it);
    	}
        // std::for_each(g.first_knot(), g.last_knot(), ...);
    	return 0;
    }
    

    Sieht ganz interessant aus. Danke.



  • Naja an manchen Stellen kann ich auf diese get_xxx_by pos nicht verzichten.

    Ich habe noch get_coord_id_by_pos, get_knot_id_by_pos, ...
    Das ist für mich ein sehr bequemer aufbau da ich zu einer passenden
    Position die id zurückbekomme..



  • darkfate schrieb:

    Meine Vorgaben sind:
    Koordinaten, Knoten, Kanten, Maschen: unique id, nach id sortiert;

    ämmm... kannst du als id nicht einfach die Position in einem vector nehmen?
    Die ist eindeutig und sortiert. Diese ganzen maps kommen mir sowieso grad seltsam vor.
    Wieso ist das nicht so

    template<typename T>
    struct coord
    {
    	T x, y, z;
    };
    
    template<typename T>
    struct knot
    {
    	typedef coord<T> coord_type;
    	coord_type location;
    };
    
    template<typename T>
    struct edge
    {
    	typedef knot<T> knot_type;
    	knot_type from, to;
    };
    
    template<typename T>
    struct face
    {
    	typedef edge<T> edge_type;
    	std::vector<egde> edges;
    };
    

Log in to reply