Concept (C++)

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 22 martie 2021; verificările necesită 18 modificări .

Conceptul  este o extensie a interfeței la șabloanele de limbaj C++ publicate în specificația tehnică ISO/IEC ISO TS 19217:2015 [1] . În esență , un concept este un set de predicate booleene plasate în spatele unei liste de parametri șablon care sunt evaluați la momentul compilarii codului sursă pentru a stabili constrângeri asupra proprietăților argumentelor care sunt acceptate ca parametri șablon [2] .

Introducerea conceptelor este asociată cu dezvoltarea ulterioară în limbajul C++ a instrumentelor bazate pe paradigma de programare generică [2] . Un concept poate fi declarat cu orice tip de șablon ( clasă șablon, șablon de funcție sau funcție membru șablon), scopul său este de a detecta inconsecvențele logice între proprietățile tipurilor de date care sunt utilizate în corpul șablonului și proprietățile datelor. tipuri care vin în model ca intrări [2] [3] .

Înainte de introducerea sa în standardul limbajului, noțiunea de concept a fost implementată în biblioteca de uz general Boost sub forma claselor de bibliotecă BCCL ( Boost Concept Checking Library ) [4] .  

Sintaxa propoziției curente (din C++20)

Definirea conceptului.

șablon < classT > _ concept EqualityComparable () { necesită ( T a , T b ) { { a == b } -> Boolean ; // Un concept care înseamnă un tip de convertit în boolean { a != b } -> Boolean ; }; }

Un șablon care utilizează conceptul (rețineți că nu există un șablon cheie).

void f ( const EqualityComparable auto & );

Conceptele vor fi implicate în alegerea funcției de aplicat din setul de supraîncărcări, alături de SFINAE . Compilatorul va prefera conceptul „cel mai greu”.

Dacă utilizați conceptul într-un inițializator, acesta va fi similar cu auto, dar codul se va compila dacă conceptul este acceptat.

Sortable auto x = f ( y ); // analog al auto x = f(y), compilat dacă rezultatul este un tip potrivit pentru Sortable

Fundal

În programarea generică, un concept  este un set de cerințe pentru un tip, astfel încât modelul de programare generic să aibă sens. De exemplu, șablonul presupune astfel de relații între tipurile de iterator It1 și It2. It2 std::copy(It1, It1, It2)

  • It1 și It2 sunt iteratoare unidirecționale.
  • Atribuirea este posibilă între tipuri *It2și .*It1

Aceste concepte sunt descrise în documentația C++ și sunt o descriere verbală a condițiilor când codul este compilat. De exemplu, dacă încercați să specializați un șablon cu parametri , It1=int*, It2=int**compilatorul va raporta că atribuirea nu este posibilă int* ← int. Cu toate acestea, există dezavantaje.

  • Eroarea va cădea în profunzimea fișierului antet STL - într-un cod complex cunoscut pentru a fi corect.
  • Adesea, textele de eroare sunt extrem de verbose și este dificil să ne dăm seama ce lipsește exact pentru ca șablonul să se specializeze.
  • Când un programator scrie un șablon, el poate părăsi accidental conceptul și să nu-l observe. Nu există nicio modalitate de a verifica acest lucru decât prin încercarea de a specializa șablonul. Pe șabloanele complexe, „verificarea specializării” nu este atât de ușoară pe cât pare - cele mai multe dintre cele mai simple tipuri acceptă o mulțime de funcții suplimentare. Deci, nu este suficient să verificați std::vector<T>tipul int: pe lângă operațiile „constructor fără parametri”, „constructor de mutare” și „atribuire cu mutare”, minimul necesar pentru un vector, un tip întreg are un constructor de copiere, un operator de atribuire, operații matematice și multe altele și nu există garanții că acestea nu sunt utilizate.

În plus, trebuie să realizați funcții care apar sau dispar în funcție de unele condiții (conformitatea sau inconsecvența conceptului ). În C++17 , șabloanele pentru aceasta sunt complicate.

Până în prezent, conceptele au fost descrise sintactic doar într-un mod limitat - de exemplu, în Java , rolul conceptelor este jucat de instrucțiuni precum class Test <T extends Testable>.

Starea actuală

Compilator Parţial In totalitate
G++ 6 zece
MSVC 2019 Nu încă
Zăngăni zece Nu încă

Note

  1. ISO/IEC TS 19217:2015 . ISO (15 noiembrie 2015). Preluat la 28 aprilie 2017. Arhivat din original la 9 decembrie 2016.
  2. 1 2 3 Ostern M. G. Concepte și modelare // Programare generică și STL: Utilizarea și extinderea Bibliotecii de șabloane standard C++ = MH Austern. Programarea generică și STL. - Sankt Petersburg: Dialectul Nevski, 2004. - P.  32 . — 544 p. - ISBN 5-7940-0119-4 .
  3. Siek J., Lee L.-Q., Lumsdaine A. 2.3 Concepte și modele // The Boost Graph Library. Ghidul utilizatorului și manualul de referință . - Addison-Wesley, 2002. - P.  27 . — ISBN 0-201-72914-8 .
  4. Siek J., Lee L.-Q., Lumsdaine A. 2.5 Concept Checking // The Boost Graph Library. Ghidul utilizatorului și manualul de referință . - Addison-Wesley, 2002. - P.  36 . — ISBN 0-201-72914-8 .