[ERLEDIGT] template einschränken



  • Z. B.:

    template<> struct
    fwd_type_if_allowed<UTM> {
        typedef std::map<int,UTM>::const_iterator it;
        static map<int, UTM>* destination;
    };
    
    map<int, UTM>* fwd_type_if_allowed<UTM>::destination = &coords;
    


  • du möchtest die id des pos -ten elements aus der map wiedergeben?

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

    mir scheint aber, dass map nicht der optimale container für dein problem ist!?
    also die position eines elements in einer map anhand der reihenfolge zu speichern, ist nicht gerade das intelligenteste...

    da ich aber vom eigtl thema keinen plan habe, kann ich das nur mal in die runde fragen... ;o)

    bb



  • unskilled schrieb:

    std::advance(i, pos);
    
      return i->first;
    

    Das gibt aua, wenn pos zu groß ist 😉



  • Michael E. schrieb:

    unskilled schrieb:

    std::advance(i, pos);
    
      return i->first;
    

    Das gibt aua, wenn pos zu groß ist 😉

    sicherlich tut es das.
    ist aufgabe des anwendes dafür zu sorgen, keine unsinnigen werte zu übergeben.
    evtl noch nen assert am anfang einfügen:

    template<typename T, typename S = typename T::size_type>
    int get_id_by_pos(const T& container, S pos)
    {
      typedef typename container::const_iterator iter_t;
    
      assert(container.size() > pos && "not a valid position");
    
      iter_t i = container.begin();
      std::advance(i, pos);
    
      return i->first;
    }
    

    bb



  • ...



  • Super!

    Anhand der hier vorgetragenen Codeschnipseln funktioniert es nun!

    #include <iostream>
    
    using namespace std;
    
    template<typename> struct fwd_type_if_allowed { };
    
    template<> struct
    fwd_type_if_allowed<std::map<int, double>> { 
      typedef std::map<int,double>::const_iterator it;
    };
    
    template<> struct
    fwd_type_if_allowed<std::map<int, char>> {
      typedef std::map<int,char>::const_iterator it;
    };
    
    template<typename T, typename S> int get_id_by_pos(const T& container, S pos)
    {
    	typedef typename fwd_type_if_allowed<T>::it iter_t;
    
    	iter_t i = container.begin();
    	std::advance(i, pos-1);
    
    	return i->first;
    } 
    
    int main(int argc, char **argv){
    
    	std::map<int, double> a;
    	std::map<int, char> b; 
    
    	a[11] = 10.1234;
    	a[22] = 20.2345;
    	a[33] = 30.4567;
    
    	b[44] = 'A';
    	b[55] = 'B';
    	b[66] = 'C';
    
    	cout << get_id_by_pos(a,2) << '\n';
    	cout << get_id_by_pos(b,3) << '\n';
    
    	return EXIT_SUCCESS;
    }
    

    Gibt es vielleicht einge Möglichkeit:

    int a = a.get_id_by_pos(1);
    int b = b.get_id_by_pos(2);
    

    Zu templatisieren? Danke schonmal an alle die geantwortet haben.



  • std::advance(i, pos-1);
    nein!? wieso -1?

    oder ist pos == 0 nicht das erste element?

    Gibt es vielleicht einge Möglichkeit:

    int a = a.get_id_by_pos(1);
    int b = b.get_id_by_pos(2);
    

    Zu templatisieren? Danke schonmal an alle die geantwortet haben.

    hm? das da hat aber nix mit "templatisieren" zu tun...
    gehen würde das - ich würd es aber so lassen.

    template<
      typename KEY,
      typename T,
      typename LESS = std::less<KEY>,
      typename ALLOC = std::allocator< std::pair<KEY, T> >
    >
    struct mymap : std::map< KEY, T, LESS, ALLOC >
    {
      KEY get_id_by_pos(size_type pos)
      {
        /*...*/
      }
    };
    

    bb



  • darkfate schrieb:

    Gibt es vielleicht einge Möglichkeit:

    int a = a.get_id_by_pos(1);
    int b = b.get_id_by_pos(2);
    

    Zu templatisieren? Danke schonmal an alle die geantwortet haben.

    Welchen Vorteil siehst du da gegenüber:

    int a = get_id_by_pos(a, 1);
    int b = get_id_by_pos(b, 2);
    

    ? Ich seh da absolut gar keinen.

    Was du da haben möchtest ist eigentlich ein schönes Beispiel für einen boost::multi_index_container. Damit kannst du deine Daten mit verschiedenen Indizes versehen, auch random access.
    http://www.boost.org/doc/libs/1_43_0/libs/multi_index/doc/tutorial/index.html



  • brotbernd schrieb:

    .. Welchen Vorteil siehst du da gegenüber: ..

    Du hast recht, es ist ok so wie es ist. Mir ging es lediglich um die Machbarkeit.

    unskilled schrieb:

    std::advance(i, pos-1);
    nein!? wieso -1?

    oder ist pos == 0 nicht das erste element?

    it.begin() setzt ihn ja auf die erste Position.
    Wenn man jetzt get_id_by_pos(1) aufruft, dann schiebt er
    den Iterator nach begin() noch um eine Position weiter.

    Für mich sind alle Fragen geklärt.
    Danke an alle Helfenden.


Anmelden zum Antworten