9

Ho esaminato alcune delle nuove funzionalità di C++ 11 e sono molto impressionato da alcune di esse, in particolare dai letterali definiti dall'utente.Come ottenere la variabile più piccola con letterali definiti dall'utente C++ 11

Questi consentono di definire i valori letterali del modulo 999_something dove something controlla ciò che viene fatto allo 999 per generare il valore letterale. Quindi, non sarà più necessario utilizzare:

#define MEG * 1024 * 1024 
int ten_meg = 10 M; 

ciò pensavo sarebbe bello implementare sottolineatura in gran numero, come 1_000_000_blah, che sarebbe partita la leggibilità di Perl, se l'idea che Perl è in qualche modo leggibile sembra abbastanza divertente per me :-)

Sarebbe utile anche per valori binari come 1101_1110_b e 0011_0011_1100_1111_b.

Ovviamente a causa dei caratteri _, questi dovranno essere di tipo raw, elaborare una stringa C e sto bene.

Ciò che I non può capire come fornire un tipo diverso in base alla dimensione dell'operando. Ad esempio:

1101_1110_b 

dovrebbe dare una char (supponendo char è 8 bit ovviamente) mentre:

0011_0011_1100_1111_b 

sarebbe fornire un tipo a 16 bit.

È possibile ottenere la lunghezza dell'operando dall'interno della funzione di operatore letterale operator"" (contando i caratteri numerici) ma il tipo restituito sembra essere fissato alla funzione, quindi non posso restituire un tipo diverso in base a questo.

questo può essere fatto con un solo suffisso _b nel quadro tipi definiti dall'utente, o devo ricorrere alla suddivisione dei tipi a parte manualmente (_b8, _b16 e così via) e di fornire funzioni per lo più duplicati?

+0

Non sono sicuro se questo funziona, ma si potrebbe provare a sovraccaricare diversi modelli di operatore letterale per vari conteggi di bit. – celtschk

+1

Apparentemente funziona: http://akrzemi1.wordpress.com/2012/10/29/user-defined-literals-part-iii/ - Penso che il modello fornito dovrebbe essere abbastanza facile da estendere per supportare più tipi. – celtschk

+2

Ripensandoci, ciò che probabilmente * not * funziona è l'uso di caratteri di sottolineatura come parte del numero: IIUC '1101_1110_b' non * chiamerà * operatore" "_ b' con l'argomento (modello)' 1101_1110', ma 'operatore ' "_1110_b' con argomento (modello)' 1101'. – celtschk

risposta

6

È necessario conoscere la dimensione della stringa e l'unico modo per ottenere ciò è disporre di un pacchetto di parametri per utilizzare sizeof.... Si dovrebbe essere in grado di ottenere quello che vuoi con un modello variadic operator"":

#include <cstdint> 
#include <type_traits> 

template<char... String> 
auto operator "" _b() 
    -> typename std::conditional<sizeof...(String) <= 8, 
     uint8_t, 
     typename std::conditional<sizeof...(String) <= 16, 
      uint16_t, 
      uint32_t 
     >::type 
    >::type 
{ 
    // Do whatever you want here 
} 

E qui è un banco di prova:

int main() 
{ 
    auto a = 10000001_b; 
    auto b = 100000001_b; 

    std::cout << std::boolalpha; 
    std::cout << std::is_same<decltype(a), uint8_t>::value << "\n"; // true 
    std::cout << std::is_same<decltype(b), uint16_t>::value << "\n"; // true 
} 

Sfortunatamente, questa soluzione non è in grado di gestire il separatore cifre. Inoltre, il macchinario std::conditional è piuttosto brutto. Probabilmente potresti lavorare qualcosa di meglio con boost::mpl::vector, boost::mpl::at e alcune operazioni aritmetiche.

+0

E ora ignorare gli 0 iniziali nella deduzione del tipo;) No seriamente, buona risposta. –

+2

@ChristianRau È più facile ignorare le persone che scrivono 0 s. Inoltre, sarebbe ... binario ottale! – Morwenn

+0

@Morwenn: Vorrei che C e C++ deprecassero le costanti che contengono uno zero iniziale e nient'altro che cifre decimali, * ma * definiscono una notazione standard per le costanti ottali in modo tale che il codice possa definire una macro (ad esempio __OCT (x)) macro che interpreta x come costante ottale in entrambi gli stili del compilatore [la mia notazione preferita personale, ma per il fatto che sarebbe stata in conflitto con la sintassi letterale definita dall'utente, sarebbe stato dire che 8x1234 sarebbe una costante ottale, 0x1234 e 16x1234 sarebbero esadecimali, 10x0sarebbero decimali, ecc. Ciò potrebbe essere generalizzato in modo soddisfacente. – supercat

Problemi correlati