Quali sono le differenze tra concetti e vincoli del modello?


96

Voglio sapere quali sono le differenze semantiche tra la proposta di concetti completi in C ++ e i vincoli del modello (ad esempio, i vincoli come apparso in Dlang o la nuova proposta di concetti-lite per C ++ 1y ).

Cosa sono in grado di fare i concetti a tutti gli effetti rispetto ai vincoli del modello?


2

Stavo ricordando 4.8 Concetti di progettazione , ma in realtà non c'è molto elencato nel modo in cui i concetti vincolano ulteriormente. Semmai, i concetti di Google ora potrebbero rivelare alcune differenze facilmente individuabili dopo aver acquisito una migliore comprensione dei vincoli della proposta.
chris

I concetti IMHO migliorano la leggibilità e forniscono capacità programmatiche più chiare, come richiesto molto tempo fa da artisti del calibro di Alexander Stepanov in "Elementi di programmazione". La proposta lite è solo una mossa verso questo per alleviare il carico di strani vincoli di tipo enable_if che sono richiesti al momento. Prima è meglio è per la programmazione generica.
dirvine

Risposte:


135

Queste informazioni sono datate. Deve essere aggiornato secondo l'ultima bozza di Concepts Lite.

La sezione 3 della proposta sui vincoli copre questo aspetto in modo ragionevole.

La proposta di concetti è stata messa in secondo piano per un breve periodo nella speranza che i vincoli (cioè i concetti-lite) possano essere sviluppati e implementati in una scala temporale più breve, attualmente mirando a qualcosa in C ++ 14. La proposta sui vincoli è concepita per agire come una transizione graduale a una definizione successiva dei concetti. I vincoli fanno parte della proposta di concetti e sono un elemento costitutivo necessario nella sua definizione.

Nella progettazione di librerie di concetti per C ++ , Sutton e Stroustrup considerano la seguente relazione:

Concetti = Vincoli + Assiomi

Per riassumere rapidamente il loro significato:

  1. Vincolo: predicato su proprietà valutabili staticamente di un tipo. Requisiti puramente sintattici. Non un'astrazione di dominio.
  2. Assiomi: requisiti semantici dei tipi che si presume siano veri. Non controllato staticamente.
  3. Concetti - Requisiti generali e astratti degli algoritmi sui loro argomenti. Definito in termini di vincoli e assiomi.

Quindi, se aggiungi assiomi (proprietà semantiche) ai vincoli (proprietà sintattiche), ottieni concetti.


Concetti-Lite

La proposta di concetti-lite ci porta solo la prima parte, i vincoli, ma questo è un passo importante e necessario verso concetti a tutti gli effetti.

Vincoli

I vincoli riguardano la sintassi . Ci danno un modo per distinguere staticamente le proprietà di un tipo in fase di compilazione, in modo da poter limitare i tipi usati come argomenti del modello in base alle loro proprietà sintattiche. Nell'attuale proposta di vincoli, sono espressi con un sottoinsieme di calcolo proposizionale utilizzando connettivi logici come &&e ||.

Diamo un'occhiata a un vincolo in azione:

template <typename Cont>
  requires Sortable<Cont>()
void sort(Cont& container);

Qui stiamo definendo un modello di funzione chiamato sort. La nuova aggiunta è la clausola require . La clausola require fornisce alcuni vincoli sugli argomenti del modello per questa funzione. In particolare, questo vincolo dice che il tipo Contdeve essere un Sortabletipo. Una cosa interessante è che può essere scritto in una forma più concisa come:

template <Sortable Cont>
void sort(Cont& container);

Ora se provi a passare qualcosa che non è considerato Sortablea questa funzione, otterrai un simpatico errore che ti dice immediatamente che il tipo dedotto per Tnon è un Sortabletipo. Se lo avessi fatto in C ++ 11, avresti avuto un orribile errore generato dall'interno della sortfunzione che non ha senso per nessuno.

I predicati dei vincoli sono molto simili ai tratti di tipo. Prendono un tipo di argomento modello e ti danno alcune informazioni al riguardo. I vincoli tentano di rispondere ai seguenti tipi di domande sul tipo:

  1. Questo tipo ha l'operatore tale e quello sovraccarico?
  2. Questi tipi possono essere usati come operandi per questo operatore?
  3. Questo tipo ha tratti del genere?
  4. Questa espressione costante è uguale a quella? (per argomenti di modello non di tipo)
  5. Questo tipo ha una funzione chiamata yada-yada che restituisce quel tipo?
  6. Questo tipo soddisfa tutti i requisiti sintattici per essere utilizzato come quello?

Tuttavia, i vincoli non intendono sostituire i tratti del tipo. Invece, lavoreranno mano nella mano. Alcuni tratti di tipo possono ora essere definiti in termini di concetti e alcuni concetti in termini di tratti di tipo.

Esempi

Quindi la cosa importante dei vincoli è che non si preoccupano della semantica di una virgola. Alcuni buoni esempi di vincoli sono:

  • Equality_comparable<T>: Controlla se il tipo ha ==entrambi gli operandi dello stesso tipo.

  • Equality_comparable<T,U>: Verifica se è presente un ==con operandi sinistro e destro dei tipi specificati

  • Arithmetic<T>: Controlla se il tipo è un tipo aritmetico.

  • Floating_point<T>: Controlla se il tipo è un tipo a virgola mobile.

  • Input_iterator<T>: Controlla se il tipo supporta le operazioni sintattiche che un iteratore di input deve supportare.

  • Same<T,U>: Controlla se il tipo specificato è lo stesso.

Puoi provare tutto questo con una build speciale di GCC .


Oltre i concetti-Lite

Ora entriamo in tutto oltre la proposta di concetti-lite. Questo è ancora più futuristico del futuro stesso. Tutto da qui in avanti probabilmente cambierà un po '.

Assiomi

Gli assiomi riguardano la semantica . Specificano relazioni, invarianti, garanzie di complessità e altre cose simili. Diamo un'occhiata a un esempio.

Mentre il Equality_comparable<T,U>vincolo ti dirà che esiste un operator== che accetta tipi Te U, non ti dice cosa significa quell'operazione . Per questo, avremo l'assioma Equivalence_relation. Questo assioma dice che quando gli oggetti di questi due tipi vengono confrontati con il operator==dare true, questi oggetti sono equivalenti. Potrebbe sembrare ridondante, ma certamente non lo è. Si potrebbe facilmente definire un file operator==che invece si comporta come un file operator<. Saresti cattivo se lo facessi, ma potresti.

Un altro esempio è un Greaterassioma. Va bene dire che due oggetti di tipo Tpossono essere confrontati con operatori >e <, ma cosa significano ? L' Greaterassioma dice che se f xè maggiore di allora y, allora yè minore di x. La specifica proposta un tale assioma assomiglia a:

template<typename T>
axiom Greater(T x, T y) {
  (x>y) == (y<x);
}

Quindi gli assiomi rispondono ai seguenti tipi di domande:

  1. Questi due operatori hanno questa relazione tra loro?
  2. Questo operatore per questo tipo significa questo?
  3. Questa operazione su quel tipo ha questa complessità?
  4. Questo risultato di quell'operatore implica che questo sia vero?

Cioè, si occupano interamente della semantica dei tipi e delle operazioni su quei tipi. Queste cose non possono essere controllate staticamente. Se questo deve essere verificato, un tipo deve in qualche modo dichiarare di aderire a queste semantiche.

Esempi

Ecco alcuni esempi comuni di assiomi:

  • Equivalence_relation: Se due oggetti si confrontano ==, sono equivalenti.

  • Greater: Ogni volta x > y, quindi y < x.

  • Less_equal: Ogni volta x <= y, quindi !(y < x).

  • Copy_equality: For xe yof type T: if x == y, un nuovo oggetto dello stesso tipo creato dalla costruzione della copia T{x} == ye fermo x == y(cioè non distruttivo).

Concetti

Ora i concetti sono molto facili da definire; sono semplicemente la combinazione di vincoli e assiomi . Forniscono un requisito astratto sulla sintassi e sulla semantica di un tipo.

Ad esempio, considera il seguente Orderedconcetto:

concept Ordered<Regular T> {
  requires constraint Less<T>;
  requires axiom Strict_total_order<less<T>, T>;
  requires axiom Greater<T>;
  requires axiom Less_equal<T>;
  requires axiom Greater_equal<T>;
}

Si noti innanzitutto che, affinché il tipo di modello Tsia Ordered, deve anche soddisfare i requisiti del Regularconcetto. Il Regularconcetto è un requisito di base che il tipo sia ben educato: può essere costruito, distrutto, copiato e confrontato.

Oltre a questi requisiti, i Orderedrequisiti Tsoddisfano un vincolo e quattro assiomi:

  • Vincolo: un Orderedtipo deve avere un'estensione operator<. Questo è staticamente controllato, quindi deve esistere.
  • Assiomi: per xe ydi tipo T:
    • x < y dà un rigoroso ordine totale.
    • Quando xè maggiore di y, yè minore di xe viceversa.
    • Quando xè minore o uguale a y, ynon è minore di xe viceversa.
    • Quando xè maggiore o uguale a y, ynon è maggiore di xe viceversa.

La combinazione di vincoli e assiomi come questo ti dà concetti. Definiscono i requisiti sintattici e semantici per i tipi astratti da utilizzare con gli algoritmi. Gli algoritmi attualmente devono presumere che i tipi utilizzati supporteranno determinate operazioni ed esprimeranno determinate semantiche. Con i concetti, saremo in grado di garantire che i requisiti siano soddisfatti.

Nella progettazione dei concetti più recenti , il compilatore controllerà solo che i requisiti sintattici di un concetto siano soddisfatti dall'argomento modello. Gli assiomi vengono lasciati deselezionati. Poiché gli assiomi denotano semantiche che non sono valutabili staticamente (o spesso impossibili da controllare completamente), l'autore di un tipo dovrebbe dichiarare esplicitamente che il loro tipo soddisfa tutti i requisiti di un concetto. Questo era noto come mappatura concettuale nei progetti precedenti, ma da allora è stato rimosso.

Esempi

Ecco alcuni esempi di concetti:

  • Regular i tipi sono costruibili, distruttibili, copiabili e possono essere confrontati.

  • Orderedsupportano i tipi operator<e hanno un rigoroso ordinamento totale e altra semantica di ordinamento.

  • Copyablei tipi sono copia costruibile, distruttibile e se xè uguale a yed xè copiato, anche la copia sarà uguale a y.

  • Iteratortipi della devono essere associati value_type, reference, difference_type, e iterator_categoryche si devono soddisfare alcuni concetti. Devono inoltre supportare operator++ed essere dereferenziabili.

La strada verso i concetti

I vincoli sono il primo passo verso una funzionalità completa dei concetti di C ++. Sono un passaggio molto importante, perché forniscono i requisiti staticamente applicabili dei tipi in modo che possiamo scrivere funzioni e classi modello molto più pulite. Ora possiamo evitare alcune delle difficoltà e della bruttezza di std::enable_ife dei suoi amici della metaprogrammazione.

Tuttavia, ci sono una serie di cose che la proposta sui vincoli non fa:

  1. Non fornisce un linguaggio di definizione dei concetti.

  2. I vincoli non sono mappe concettuali. L'utente non ha bisogno di annotare specificamente i loro tipi in quanto soddisfano determinati vincoli. Vengono controllate staticamente le semplici funzionalità del linguaggio in fase di compilazione.

  3. Le implementazioni dei modelli non sono vincolate dai vincoli sui relativi argomenti del modello. Cioè, se il tuo modello di funzione fa qualcosa con un oggetto di tipo vincolato che non dovrebbe fare, il compilatore non ha modo di diagnosticare ciò. Una proposta di concetti completa sarebbe in grado di farlo.

La proposta di vincoli è stata progettata specificamente in modo che una proposta completa di concetti possa essere introdotta sopra di essa. Con un po 'di fortuna, quella transizione dovrebbe essere una corsa abbastanza fluida. Il gruppo di concetti sta cercando di introdurre vincoli per C ++ 14 (o in un rapporto tecnico subito dopo), mentre i concetti completi potrebbero iniziare ad emergere intorno a C ++ 17.


5
Va notato che concepts-lite non controlla i vincoli rispetto all'implementazione del template stesso. Quindi potresti affermare che qualsiasi DefaultConstructable può essere usato, ma il compilatore non ti impedirà di usare un costruttore di copie per sbaglio. Una proposta di concetti più completa sarebbe.
Nicol Bolas

24
Questa è una prima bozza ?!
Nicol Bolas

2
@sftrabbit, risposta molto buona. Ma ho una domanda: come un compilatore verificherà che un tipo soddisfi i requisiti semantici di un concetto?
Rayniery

1
(Con molta incertezza) gli "assiomi" verranno controllati durante l'esecuzione o serviranno solo come una sorta di tag di promessa?
Red XIII

4
@ScarletAmaranth: Perché si riduce a dimostrare automaticamente un teorema in un tempo limitato e finito. Ci sono due ostacoli a questo: 1. Dimostrare qualsiasi teorema in un tempo limitato e finito che è estremamente difficile in teoria e impossibile con la tecnologia attuale. 2. Non puoi provare un assioma, a meno che la dimostrazione non sia basata su altri assiomi. (Nel qual caso matematicamente diventa "non un assioma") Questi assiomi hanno lo scopo di dire al compilatore "Ovviamente puoi invertire il confronto se lo ritieni utile ...", oppure "Sì, un EmptySet usato sempre in un'intersezione dà lo stesso risultato. "
Laurent LA RIZZA


4

I miei 2 centesimi:

  1. La proposta concetti-Lite non è destinata a fare "il controllo di tipo" del modello di implementazione . Cioè, Concepts-lite garantirà (teoricamente) la compatibilità dell'interfaccia nel sito di istanziazione del modello. Citando dall'articolo: "concepts lite è un'estensione di C ++ che consente l'uso di predicati per vincolare gli argomenti del template". E questo è tutto. Non dice che il corpo del modello verrà verificato (in isolamento) rispetto ai predicati. Ciò probabilmente significa che non esiste una nozione di prim'ordine di archetipi quando si parla di concetti-lite. Gli archtypes, se non ricordo male, nelle proposte di concetti pesanti sono tipi che offrono niente di meno e niente di più per soddisfare l' implementazione del modello.

  2. concepts-lite usa funzioni constexpr glorificate con un po 'di trucco di sintassi supportato dal compilatore. Nessuna modifica nelle regole di ricerca.

  3. I programmatori non sono tenuti a scrivere mappe concettuali.

  4. Infine, citando di nuovo "La proposta sui vincoli non affronta direttamente la specificazione o l'uso della semantica; è mirata solo al controllo della sintassi". Ciò significherebbe che gli assiomi non rientrano nello scopo (finora).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.