2016-05-25 7 views
10

infatti non so come essere molto preciso.C++ funzione slash operatore lambda espressione

Oggi, ho passato in rassegna la seguente pagina:

http://siliconframework.org/docs/hello_world.html

ho trovato la seguente sintassi:

GET/_hello = []() { return D(_message = "Hello world."); } 

ho trovato "GET" può essere una funzione da un'espressione lambda, ma non posso capire cosa significa "/" e "_hello" qui e come si collegano a qualcosa di significativo.

Inoltre, che cos'è "_message ="?

BTW, la mia conoscenza C++ primaria è precedente al C++ 11.

Ho cercato su Google un bel po '.

Qualcuno può gentilmente dare una spiegazione?

+2

Immagino che 'operator /' –

+2

'D' sia spiegato in quella pagina. Il/è solo la libreria che fa apparire il codice più vicino a ciò che assomiglia. – chris

+4

Sembra un'EDSL che utilizza ampiamente l'overloading dell'operatore. – Quentin

risposta

11

Questa libreria utilizza il cosiddetto linguaggio specifico di dominio incorporato, in cui altera la sintassi del C++ e del preprocessore in modi che consentono a un linguaggio apparentemente diverso di essere solo un'altra parte di un programma C++.

In breve, magia.

La prima 'di magia sta nel:

iod_define_symbol(hello) 

che è una macro che genera l'identificatore _hello di tipo _hello_t.

Viene inoltre creato un tipo _hello_t che eredita da un helper CRTP denominato iod::symbol<_hello_t>.

_hello_t ignora vari operatori (tra cui operator= e operator/) in modi che non fanno quello che ci si aspetterebbe normalmente oggetti C++ a comportarsi.

GET/_hello = []() { return D(_message = "Hello world."); } 

quindi questo chiama

operator=(
    operator/(GET, _hello), 
    /* lambda_goes_here */ 
); 

simile nel lambda:

D(_message = "Hello world."); 

è

D(operator=(_message, "Hello world.")); 

operator/ e operator= può fare quasi nulla.

Nel caso D, = non fare alcuna assegnazione - invece, si costruisce una struttura che sostanzialmente dice "il campo chiamato "message" viene assegnato il valore "Hello world."

_message sa che è chiamato "message" perché. è stato generato da una macro iod_define_symbol(message) dove hanno preso la stringa message e memorizzati con il tipo _message_t, e creato la variabile _message che è un'istanza di quel tipo.

D accetta un numero o f tali coppie chiave/valore e le raggruppa insieme.

Il lambda restituisce questo pacchetto.

Quindi []() { return D(_message = "Hello world."); } è un lambda che restituisce un fascio di allegati coppia-chiave, scritti in modo strano.

Abbiamo quindi invocato operator= con GET/_hello sul lato sinistro.

GET è un altro oggetto globale con operator/ sovraccarico su di esso. Non l'ho rintracciato. Supponiamo che sia di tipo iod::get_t (ho inventato quel nome: di nuovo, non ho cercato di che tipo è, e non importa)

Quindi lo iod::get_t::operator/(iod::symbol<T> const&) è sovraccarico per generare ancora un altro tipo di supporto. Questo tipo ottiene il nome di T (in questo caso "hello") e attende che venga assegnato da un lambda.

Quando assegnato a, non fa quello che ti aspetti. Invece, si attiva e crea un'associazione tra "hello" e richiama quella lambda, in cui è previsto che lambda restituisca un insieme di coppie chiave-valore generate da D.

Passiamo quindi a una o più associazioni di questo tipo a http_api, che raccoglie questi bundle e crea i dati necessari per eseguire un server Web con quelle query e quelle risposte, includendo eventualmente le diciture "Sto diventando un server http ".

sl::mhd_json_serve quindi prende quei dati e un numero di porta e in realtà esegue un server web.

Tutto questo è un mucchio di strati di astrazione per rendere più semplice la riflessione. Le strutture generate hanno identificatori C++ e stringhe simili. Le stringhe simili sono esposte in esse e quando viene generato il codice serializzazione json (o deserializzazione), tali stringhe vengono utilizzate per leggere/scrivere i valori JSON.

I macro esistono semplicemente per semplificare la scrittura del foglio di riscaldamento.

Le tecniche che potrebbero essere utili per la lettura includono inoltre "modelli di espressione", "riflessione", "CRTP", incorporato "Dominio specifico del dominio" se si vuole sapere cosa sta succedendo qui.

Alcuni di questi contengono "menzogne ​​ai bambini" minori - in particolare, la sintassi dell'operatore non funziona in modo simile a quanto implicito. (a/b non è equivalente a operator/(a,b), in quanto il secondo non chiama l'operatore membro /. Capire che si tratta di solo le funzioni è ciò che intendo, non che la sintassi sia la stessa.)

@mattheiuG (l'autore di questo quadro) ha condiviso these slides in un commento sotto questo post che spiega ulteriormente D ei _message gettoni e il quadro.

+0

Plus 1 per la spiegazione dettagliata e ha senso. Grazie. – Swtsvn

+1

Puoi leggere ulteriori informazioni sui simboli e su come D (...) costruisce oggetti in queste diapositive: http://www.slideshare.net/MatthieuGarrigues/high-per?qid=e6077f33-8af5-4c16-867f-b3879a8a0174&v=qf1&b = & from_search = 1 #. C'è anche una breve panoramica della struttura in silicio. –

+0

Volevo solo dirti che questa è una risposta fantastica e ho imparato molto leggendolo! – Will

7

Non è la sintassi C++ standard, è invece specifica per il framework. Gli elementi preceduti da un carattere di sottolineatura (_hello, _message ecc.) Vengono utilizzati con un generatore di definizioni di simboli che viene eseguito e crea le definizioni necessarie prima della compilazione.

Sono disponibili ulteriori informazioni alla fine di questa pagina: http://siliconframework.org/docs/symbols.html. Qt fa una cosa simile con il suo strumento moc.

+4

che cosa * non è standard * su questa sintassi? –

+1

@PiotrSkotnicki è necessario utilizzare un precompilatore per generare i simboli prefissi sottolineatura. – mcarton

+7

ma 'GET/_hello = []() {restituisce D (_message =" Hello world. "); } 'stesso è fattibile in C++ –