Analiza cea mai supărătoare

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Analiza cea mai deranjantă este o formă de rezoluție a ambiguității sintactice C ++ , definită în secțiunea 8.2 din standard. [1] , determinat de faptul că sintaxa pentru inițializarea unei variabile este în unele cazuri ambiguă cu cea a unei declarații de funcție. Termenul cel mai supărător a fost introdus de Scott Meyers în Effective STL (2001). [2]

Exemplu cu clase și obiecte

Următorul este un exemplu de afirmație sau definiție ambiguă:

 clasa Timer {
 public :
  Temporizator ();
};

clasa TimeKeeper {
 public :
  TimeKeeper ( const Timer & t );

  int get_time ();
};

int main () {
  TimeKeeper time_keeper ( Timer ());
  întoarce-te cu timpul . get_time ();
}

Linia

 TimeKeeper time_keeper ( Timer ());

ar putea fi interpretat ca

  1. definirea unei time_keeper variabile a TimeKeeper clasei, inițializată cu o instanță anonimă a Timer clasă;
  2. declarația unei funcții time_keeper cu tip de returnare TimeKeeper și un singur parametru (fără nume) de tip pointer pentru a funcționa fără parametri și cu tip de revenire Timer .

Standardul necesită interpretarea acestei linii în al doilea mod, astfel încât următoarea linie nu va fi validă. De exemplu, g ++ returnează următorul mesaj de eroare:

 $ g ++ -c time_keeper.cc
time_keeper.cc: În funcția 'int main ()':
time_keeper.cc:15: eroare: cerere pentru membru 'get_time' în 'time_keeper', care este
de tip non-clasă „TimeKeeper (Timer (*) ())”

deoarece time_keeper este o funcție declarată pe linia anterioară, deci nu este posibilă apelarea get_time() pe ea.

Clang ++ oferă un mesaj de avertizare:

 $ clang ++ time_keeper.cc
timekeeper.cc:14:25: avertisment: parantezele au fost dezambiguate ca declarație de funcție
      [-Wvexing-parse]
  TimeKeeper time_keeper (Timer ());
                        ^ ~~~~~~~~
timekeeper.cc:14:26: notă: adăugați o pereche de paranteze pentru a declara o variabilă
  TimeKeeper time_keeper (Timer ());
                         ^
                         ()
timekeeper.cc:15:21: eroare: tipul de bază de referință membru „TimeKeeper (Timer (*) ())” nu este
      structură sau uniune
  return time_keeper.get_time ();
         ~~~~~~~~~~~ ^ ~~~~~~~~

Pentru ca declarația să fie interpretată ca o definiție a variabilei inițializată, puteți adăuga o pereche suplimentară de paranteze:

 TimeKeeper time_keeper ( ( Timer ()) );

Exemplu cu distribuție funcțională

Un alt exemplu implică utilizarea distribuției funcționale, atunci când este utilizată pentru a converti valoarea unei expresii transmise apoi ca variabilă sau ca parametru la un constructor.

 void f ( dublu adouble ) {
  int i ( int ( adouble ));
}

În acest caz, i este interpretat ca o definiție a funcției, echivalentă cu următoarea

 // ia un număr întreg și returnează un număr întreg
int i ( int adouble );

Pentru a dezambigua expresia care trebuie interpretată ca o declarație variabilă, puteți utiliza aceeași tehnică ca în exemplul anterior sau puteți înlocui distribuția funcțională cu o distribuție în stil C

 // declară o variabilă numită „i”
int i (( int ) adouble );

sau puteți utiliza operatorul de turnare C ++ corespunzător

 // declară o variabilă numită „i”
int i ( static_cast < int > ( adouble ));

Sintaxă de inițializare uniformă

Standardul C ++ 11 a introdus sintaxa uniformă de inițializare , care uniformizează sintaxa pentru inițializarea obiectelor sau variabilelor cu cea pentru matrice și permite evitarea oricărei ambiguități cu declarația de funcții. Linia problemă din primul exemplu poate fi rescrisă ca:

 TimeKeeper time_keeper { Timer {}};

Notă

  1. ^ ISO / IEC (2003). ISO / IEC 14882: 2003 (E): Limbaje de programare - C ++ §8.2 Rezoluția ambiguității [dcl.ambig.res]
  2. ^ Scott Meyers , STL eficient: 50 de moduri specifice de a vă îmbunătăți utilizarea bibliotecii de șabloane standard , Addison-Wesley, 2001, ISBN 0-201-74962-9 .

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT