Koncept (C++)

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 22 mars 2021; kontroller kräver 18 redigeringar .

Konceptet  är en gränssnittstillägg till C++-språkmallarna publicerade i ISO/IEC ISO TS 19217:2015 [1] teknisk specifikation . I sin kärna är ett koncept en uppsättning booleska predikat placerade bakom en lista med mallparametrar som utvärderas vid källkodens kompileringstid för att sätta begränsningar på egenskaperna hos argumenten som accepteras som mallparametrar [2] .

Införandet av begrepp är förknippat med vidareutvecklingen i C++-språket av verktyg baserade på det generiska programmeringsparadigmet [2] . Ett koncept kan deklareras med vilken typ av mall som helst ( mallklass , funktionsmall eller mallmedlemsfunktion), dess syfte är att upptäcka logiska inkonsekvenser mellan egenskaperna hos datatyper som används i mallens kropp och egenskaperna hos data typer som kommer i mönster som ingångar [2] [3] .

Innan dess introduktion i språkstandarden implementerades idén om ett koncept i Boost - biblioteket för allmänna ändamål i form av BCCL -biblioteksklasser ( Boost Concept Checking Library ) [4] .  

Syntax för den aktuella meningen (från C++20)

Begreppsdefinition.

mall < classT > _ koncept EqualityComparable ( ) { requires ( Ta , T b ) { { a == b } -> Boolean ; // Ett begrepp som betyder en typ som ska konverteras till boolesk { a != b } -> Boolean ; }; }

En mall som använder konceptet (observera att det inte finns något mallsökord).

void f ( const EqualityComparable auto & );

Koncepten kommer att vara involverade i valet av vilken funktion som ska tillämpas från uppsättningen av överbelastningar, tillsammans med SFINAE . Kompilatorn kommer att föredra det "svåraste" konceptet.

Om du använder konceptet i en initialiserare kommer det att likna auto, men koden kompileras om konceptet stöds.

Sorterbar auto x = f ( y ); // analog av auto x = f(y), kompilerad om resultatet är en typ som lämpar sig för Sortable

Bakgrund

I generisk programmering är ett koncept  en uppsättning krav för en typ så att det generiska programmeringsmönstret är vettigt. Till exempel antar mallen sådana relationer mellan iteratortyperna It1 och It2. It2 std::copy(It1, It1, It2)

  • It1 och It2 är enkelriktade iteratorer.
  • Tilldelning är möjlig mellan typer *It2och .*It1

Dessa begrepp beskrivs i C++-dokumentationen, och de är en verbal beskrivning av villkoren när koden kompileras. Till exempel, om du försöker specialisera en mall med parametrar kommer It1=int*, It2=int**kompilatorn att rapportera att tilldelning inte är möjlig int* ← int. Det finns dock nackdelar.

  • Felet kommer att falla ut i djupet av STL-huvudfilen - i en komplex kod som är känd för att vara korrekt.
  • Ofta är feltexterna extremt mångsidiga, och det är svårt att lista ut exakt vad som saknas för att mallen ska specialisera sig.
  • När en programmerare skriver en mall kan han av misstag lämna konceptet och inte lägga märke till det. Det finns inget sätt att kontrollera detta förutom genom att försöka specialisera mallen. På komplexa mallar är "specialiseringskontroll" inte så lätt som det verkar - de flesta av de enklaste typerna stöder många extrafunktioner. Så det räcker inte att kontrollera std::vector<T>typen int: förutom operationerna "konstruktor utan parametrar", "flytta konstruktör" och "tilldela med flytta", det minimum som krävs för en vektor, har en heltalstyp en kopiakonstruktor, en uppdragsoperatör, matematiska operationer och mycket mer, och det finns inga garantier för att de inte används.

Dessutom måste du göra funktioner som visas eller försvinner beroende på vissa förhållanden (konformitet eller inkonsekvens av konceptet ). I C++17 är mallar för detta komplicerade.

Än idag har begrepp endast beskrivits syntaktiskt på ett begränsat sätt - till exempel i Java spelas begreppens roll av uttalanden som class Test <T extends Testable>.

Nuvarande tillstånd

Kompilator Delvis Fullt
G++ 6 tio
MSVC 2019 Inte än
Klang tio Inte än

Anteckningar

  1. ISO/IEC TS 19217:2015 . ISO (15 november 2015). Hämtad 28 april 2017. Arkiverad från originalet 9 december 2016.
  2. 1 2 3 Ostern M. G. Koncept och modellering // Generisk programmering och STL: Använda och utöka C++ standardmallbiblioteket = MH Austern. Generisk programmering och STL. - St Petersburg: Nevsky Dialect, 2004. - S.  32 . — 544 sid. - ISBN 5-7940-0119-4 .
  3. Siek J., Lee L.-Q., Lumsdaine A. 2.3 Koncept och modeller // The Boost Graph Library. Användarhandbok och referensmanual . - Addison-Wesley, 2002. - S.  27 . — ISBN 0-201-72914-8 .
  4. Siek J., Lee L.-Q., Lumsdaine A. 2.5 Konceptkontroll // The Boost Graph Library. Användarhandbok och referensmanual . - Addison-Wesley, 2002. - S.  36 . — ISBN 0-201-72914-8 .