Perché stringa :: append operazioni comporta in modo strano?
-
19-09-2019 - |
Domanda
un'occhiata al seguente codice semplice:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("1234567890");
string::iterator i1 = s.begin();
string::iterator i2 = s.begin();
string s1, s2;
s1.append(i1, ++i1);
s2.append(++i2, s.end());
cout << s1 << endl;
cout << s2 << endl;
}
Che cosa vi aspettate l'uscita di essere?
vuoi, come me, aspetta che sia:
1
234567890
sbagliato! è:
234567890
vale a dire. la prima stringa è vuota.
cuciture che operatore prefisso incremento è problematico con iteratori. o mi sto perdendo qualcosa?
Soluzione
Non è un bug.
L'ordine in cui gli argomenti di
s1.append(i1, ++i1);
vengono valutati non è specificato dalla norma. Il compilatore è libero di utilizzare qualsiasi ordine di sua scelta. In questo caso, si valuta il secondo argomento (++i1
) prima del primo (i1
) e si specifica una gamma nulla da copiare.
Altri suggerimenti
Ti manca qualcosa: questo non ha davvero nulla a che fare con iteratori. L'ordine in cui vengono valutate argomenti a una funzione non è specificato. Come tale il vostro: append(i1, ++i1);
dipenderebbe comportamento non specificato, a prescindere dal tipo di i1
. Solo per esempio, dato qualcosa di molto semplice come:
void print(int a, int b) {
std::cout << a << " " << b << "\n";
}
int main() {
int a =0;
print(a, ++a);
return 0;
}
L'output potrebbe perfettamente ragionevolmente essere il "0 1" ti sembra di aspettare, ma potrebbe anche essere perfettamente ragionevole: "1 1". Dal momento che questo non è specificato, potrebbe cambiare da una versione del compilatore per il prossimo, o anche con lo stesso compilatore quando si cambia bandiere, o (in teoria) potrebbe variare a seconda della fase della luna ...
C ++ implementazioni sono liberi di valutare le argomentazioni in qualsiasi ordine. In questo caso, se ++ i1 viene valutata per prima, si otterrà una stringa vuota.
La serie C ++ non specifica nulla circa l'ordine in cui vengono valutati gli argomenti della funzione, il che rende attuazione dipendente. C ++ richiede che gli argomenti a una funzione di essere completamente valutati (e tutti gli effetti collaterali inviate) prima di entrare nel funzionamento, ma l'implementazione è libero di valutare gli argomenti in qualsiasi ordine
Nel tuo caso i++
preso valutati prima di prendere entrambi i parametri stessi, con conseguente una stringa vuota.
Più informazioni su questo comportamento qui in comp.compilers newsgroup