virtual template member function workaround gesucht



  • Wenn die Hauptzeit in dieser Funktion liegt und weniger bei Hinzufügen/Entfernen, könntest du auch für jeden Typ einen Referenzzähler einbauen und dann beim Abfragen auf 0 vergleichen.



  • C++ kennt kein for_each als Sprachkonstrukt und main muss int zurückgeben. Hässlicher MSVC Schrott.



  • Wieso kannst du nicht einfach zusätzliche Container für deine ASkill und BSkill Objekte machen?



  • dot schrieb:

    Wieso kannst du nicht einfach zusätzliche Container für deine ASkill und BSkill Objekte machen?

    nurf schrieb:

    // 100 weitere, mehrere Veerbungsebenen
    

    Bisschen unschön.



  • @nurf: Warum genau musst du denn überhaupt rausfinden ob im Container ein ASkill drin ist?



  • dot schrieb:

    @nurf: Warum genau musst du denn überhaupt rausfinden ob im Container ein ASkill drin ist?

    Vermutlich will er ein Item o.ä. hinzufügen, falls der Spieler eine gewisse Fähigkeit besitzt.



  • Pi:

    error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    

    Aber gut, dass du maulst 🙄



  • Michael E. schrieb:

    Pi:

    error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    

    Aber gut, dass du maulst 🙄

    Da hier ein C++-Forum ist, darf er maulen 😉



  • C++Forum schrieb:

    Da hier ein C++-Forum ist, darf er maulen 😉

    Natürlich darf man sich über main ohne expliziten Rückgabewert beschweren. Das als "hässlichen MSVC-Schrott" abzutun, ist aber unüberlegter Unsinn, weil der VC das gar nicht schluckt.



  • Das bezog sich auch auf for_each du Pfeife. Lern Texte verstehen.



  • 314159265358979 schrieb:

    Das bezog sich auch auf for_each du Pfeife. Lern Texte verstehen.

    http://msdn.microsoft.com/en-us/library/c4x1w65f.aspx 😕



  • Geb ich gleich mal an dich weiter.



  • Mir ist schon klar was du gemeint hast.

    Aber bevor du dich hier so aufspielst, solltest du erstmal deine eigenen Texte fixen...



  • Vielleicht hast du auch einfach nur nicht verstanden.



  • Du meintest wohl dass MSVC noch nicht die neue range-based for Loop unterstützt!?
    Denn for_each ist Teil der Standardbibliothek und das unterstützt es natürlich...



  • Schritt 1: Code des TE nochmal ansehen.
    Schritt 2: Stichwort: Extension



  • Versuch mal folgendes, um der rtti Beine zu machen:

    inline unsigned int next_id()
    {
        static unsigned int current_id = 1;
    
        return current_id++;
    }
    template< class Type >
    class t_id
    {
        static const unsigned int value;
    };
    template< class Type >
    const unsigned int t_id< Type >::value = next_id();
    

    t_id< X >::value ist jetzt für jede Klasse einzigartig (Achtung: funktioniert vermutlich nicht, wenn dlls im Spiel sind).
    Jetzt kannst du noch die Suche von O( n ) auf O( 1 ) bringen:
    Statt linearer Suche verwendest du ein Hilfsarray. lookup_vector[ t_id< Type >::value ] soll die Anzahl der Objekte eines bestimmten Typs beinhalten. Dazu muss sich jedes Objekt in dem lookup_vector registrieren (inklusive aller base classes!), wenn es in den Container aufgenommen wird und abmelden, wenn es entfernt wird:

    template< class BaseType , class DerivedType >
    class derived_helper
      : public BaseType
    {
    public:
        static void add_indices( std::vector< unsigned int >& lookup_vector )
        {
            ++lookup_vector[ t_id< DerivedType >::value ];
            BaseType::add_indices( lookup_vector );
        }
        static void remove_indices( ... )
        {
             ...
        }
    };
    

    Wenn du davor hattest

    A;
    B : A;
    

    machst du jetzt halt

    A;
    B : derived_helper< A , B >
    

    Du musst also die alte codebase verändern, darum kommst du wohl nicht rum (sind aber minimale Änderungen, denke ich).
    Wenn du jetzt ein Objekt zu deinem Container hinzufügst, rufst du für den jeweiligen Type eben die add_indices funktion mit deinem std::vector< unsigned int > lookup_vector auf, wenn du eines entfernst die remove_indices funktion (Anm.: Falls du Objekte über einen base pointer übergibst muss die Funktion virtuell und nicht statisch sein).
    Deine has< T > funktion wird dann einfach ein

    template< class Type >
    bool has()
    {
        return lookup_vector[ t_id< Type >::value ] != 0;
    }
    

    Statt einem lookup_vector kann man denke ich auch eine andere Datenstruktur verwenden, beispielsweise ein set. Dadurch gewinnt man vielleicht etwas Speicher, verliert aber Zeit und hat wieder beim eine binary search drinnen, verliert also O( 1 ). Ist davon abhängig, wie viele verschiedene Typen tatsächlich im container gespeichert werden, was sinnvoller ist.



  • @dot: Der Code von nurf erinnert eher an etwas wie das:

    #define for_each(i, l) \
        for (__decltype((l).begin()) i=(l).begin(), i##_end=(l).end();
             i != i##_end; ++i)
    

    So nutzt nurf den Wurf:

    template <typename T> bool has()
      {
        for_each(skill, skills)
        {
           // hier liegt das Problem
           if (dynamic_cast<T*>(skill) != 0 )
           { return true; } // Guck mal da: returniert aus has()
        }
        return false;
      }
    


  • 314159265358979 schrieb:

    Schritt 1: Code des TE nochmal ansehen.
    Schritt 2: Stichwort: Extension

    MSVC hat keine for_each Extension, nur eine for each Extension. Das muss also irgendein Makro sein...



  • Abgesehen davon:

    main(...)
    

    Die "..." stören niemanden oder was? Vielleicht darüber nachgedacht, dass der TE nur Pseudocode gepostet hat, um zu veranschaulichen, worum es geht? Statt Hilfe kommt nur dummes Gelaber von language lawyern (naja, eigentlich nur einem) der keinem was bringt... wirklich unnötig.


Anmelden zum Antworten