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!
-
- das dürfte nicht compilieren
- 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
-
- 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.