2016-05-21 15 views
15

Secondo N4295 C++ 17 mi permetterà di calcolare la somma di un numero imprecisato di argomenti così:espressioni pieghevole in C++ 17 - Usecase per gli operatori di confronto

template<typename ... T> 
int sum(T...t) 
{ 
    return (... + t); 
} 

Il documento afferma inoltre che potrebbe usare operatori come == o> invece di +. Qualcuno può venire con un esempio ragionevole di quando vorrei usare == o> in un simile costrutto?

(mi rendo conto che le persone possono definire == e> per fare cose strane alle classi strane, ma sicuramente che viola le buone pratiche. La scrittura a > b > c > d è quasi mai una buona idea, vero?)

+0

Se si utilizza una piega binaria con qualche elemento di partenza speciale, si potrebbe dire '(apply_op() == ... == t)' per rendere l'operatore 'apply_op'' == 'fare il diritto cosa? –

+0

Da quello che ricordo, le pieghe unarie sono state rimosse per +. Dovresti scrivere '(T {} + ... + t)' o '(t + ... + T {})' (o qualunque valore abbia senso per te). – chris

+0

@chris Sono stati rimossi solo quando il pacchetto parametri è vuoto. Finché c'è almeno un elemento in '... t' la funzione sopra funziona ancora come previsto. – Morwenn

risposta

10

Sarei una caratteristica interessante se i confronti concatenati sono gestiti come in Python dove a < b < c viene interpretato come a < b and b < c con una singola valutazione di b. Sfortunatamente, questo non è il caso del C++ e anche in casi strani, gli operatori di comparazione pieghevoli non hanno praticamente senso.

Nota che c'era a proposal (P0313) per rimuovere effettivamente gli operatori ==, !=, <, >, <= e >= dagli operatori gestite da espressioni piegatura del tutto. È stato discusso durante la riunione del comitato di giugno 2016 a Oulu. La motivazione per la rimozione è stata piuttosto breve:

Gli operatori di confronto non hanno molto senso nelle espressioni di piegatura; si espandono in espressioni che hanno effetti sorprendenti e sono quindi utili solo per dsl-metaprogrammers. [...] Sarebbe bello poter correggere espressioni come a < b < c. Ciò richiederebbe una macchina del tempo. Sembra che non sia possibile ripetere il problema per le espressioni di piegatura.

che dicono che la proposta è stata respinta.

+1

Si può sovraccaricare tali operatori in modo che si comportino in modo diverso, in cui la piegatura si tradurrebbe in qualche caratteristica piacevole. Forse;) – Zereges

+2

Preferirei un "mix folding" in cui puoi dire "t op1 ... op2" per fold unari e "t op1 ... op2 e" per le pieghe binarie che si espande a "t1 op1 t2 op2 t2 op1 t3 ... ". –

+0

@ JohannesSchaub-litb È ora di scrivere un'altra proposta? : p – Morwenn

0

In base all'utilizzo sarebbe expression templates, per il quale gli operatori di confronto (ad esempio operator ==) restituiscono un oggetto di classe anziché bool.

Anch'io fatico a tirar fuori un esempio utile anche qui, però.

0

Questa non è una "piegatura diretto della sola ==", ma piuttosto un "& & piegato con un'espressione che coinvolge ==". Tuttavia questa è la soluzione che uso per confrontare i valori e forse questo è anche il tipo di applicazione che avevi in ​​mente.

questo funziona per me, sia per g ++ e clang ++

template <typename TYPE, typename... TYPE_TAIL> 
constexpr bool same_value([[maybe_unused]] TYPE value, TYPE_TAIL... value_tail) 
{ 
    return (... && (value == value_tail)); 
} 

static_assert(same_value(3)); 
static_assert(same_value(3, 3)); 
static_assert(!same_value(3, 1)); 
static_assert(same_value(3, 3, 3)); 
static_assert(!same_value(3, 1, 3)); 

int main() {} 

Compilation:

clang++ -std=c++1z testFold.cpp -o testFold 

(versione: La versione clang 5.0.0- + rc2-1 (tag/RELEASE_500/RC2))

o

g++ -std=c++17 testFold.cpp -o testFold 

(versione: g ++ (Debian 7.2.0-8) 7.2.0)

Il [[maybe_unused]] impedisce compilatore per avvisare quando same_value(one_arg) viene chiamato con un solo argomento quanto in questo caso la funzione restituisce il valore neutro per l'operatore & & (che è true).