spezialisiertes std::copy?



  • Ich will für meine Klasse "String" ein spezialisiertes std::copy erstellen:

    namespace std {
        template<String::const_iterator, String::iterator> 
            inline String::iterator 
            copy(String::const_iterator first, String::const_iterator last, String::iterator dest)
        {
            return memcpy(dest, first, dest-first);
        }
    };
    
    String s = "test \n test", t = "test \n test \n test";
    std::copy(s.begin(), s.end(), t.begin());
    

    Im generierten Assemblercode wird aber nicht meine Version genommen. Warum? Wie muss ich es verbessern?



  • Hast du es included?



  • klar!



    1. das dürfte nicht compilieren
    2. sei froh, denn der memcpy-Aufruf ist Unsinn, der dritte Parameter sollte last-first sein


  • Liefern Dein begin/end vielleicht String::iterator, also nicht const? Dann baut er vielleicht aus dem template in std einen besseren Treffer zusammen.

    MfG Jester



  • @Jester: ich hab ne const und ne nicht-const Variante
    @Bashar: 1) macht es aber; warum nicht?
    2) gefixt



  • Probier mal das hier:

    const String s = "test \n test"
    String t = "test \n test \n test";
    std::copy(s.begin(), s.end(), t.begin());
    

    Würd mich mal interessieren, was er dazu meint.

    MfG Jester



    1. weil die Syntax falsch ist. In die template-Klammern gehört eine Liste von Template-Parametern. Die kann auch leer sein, dann isses eine totale Spezialisierung.

    so vielleicht:

    namespace std {
      template <>
      String::iterator copy(String::const_iterator first, 
                            String::const_iterator last,
                            String::iterator dest) { ... }
    }
    


  • Frage: Macht das normale copy nicht genau das selbe wie er hier versucht zu implementieren?



  • Danke! Jetzt gehts!



  • Original erstellt von <Mööööp>:
    Frage: Macht das normale copy nicht genau das selbe wie er hier versucht zu implementieren?

    Bei mir (VC++ 7.1) nimmt er memmove statt memcpy.



  • stimmt, mit memcpy gibts Probleme, wenn Quell- und Zielbereich sich überlappen.



  • richtig, aber ich garantiere, dass sie es nicht tun!



  • Was ist eigentlich schneller?

    ; 95   :        while (first != last)
    
        cmp ecx, edx
        je  SHORT $L8947
        push    esi
    $L8946:
    
    ; 96   :            *dest++ = *first++;
    
        mov esi, DWORD PTR [ecx]
        mov DWORD PTR [eax], esi
        add ecx, 4
        add eax, 4
        cmp ecx, edx
        jne SHORT $L8946
        pop esi
    $L8947:
    
    ; 97   :        return dest;
    ; 98   :    }
    
        ret 0
    

    oder

    ; _first$ = eax
    ; _last$ = ecx
    ; _dest$ = edx
    
    ; 93   :    {
    
        push    esi
        mov esi, eax
    
    ; 94   :        return static_cast<String::char_type*>(memcpy(dest, first, last-first));
    
        sub ecx, esi
        push    edi
        sar ecx, 2
        mov edi, edx
        mov edx, ecx
        shr ecx, 2
        mov eax, edi
        rep movsd
        mov ecx, edx
        and ecx, 3
        rep movsb
        pop edi
        pop esi
    
    ; 95   :        /*while (first != last)
    ; 96   :            *dest++ = *first++;
    ; 97   :        return dest;*/
    ; 98   :    }
    
        ret 0
    

    ?



  • wahrscheinlich das zweite, zumindest für längere Strings, wegen dem movsd



  • ok, ich frag zur Sicherheit nochmal im ASM-Forum



  • @Bashar: IMHO war das mal die alte Temaplte-Spezialisierungs Synthax vor 98. Bitte nicht schlagen, wenns falsch ist.


Log in to reply