2012-06-04 3 views
10

Il nuovo concetto letterale definito dall'utente in C++ suggerisce alcuni usi molto interessanti di stringa-letterali, come ad esempio:È possibile digitare fortemente i valori letterali definiti dall'utente basati su stringhe?

"Goodbye %s world"_fmt("cruel"); 
"Goodbye %s world"_fmt(123); // Error: arg 1 must be convertible to const char* 

R"(point = \((\d+), (\d+)\))"_re; // Builds DFA at compile-time. 

typedef table< 
    column<"CustId"_name , std::string>, 
    column<"FirstName"_name, std::string>, 
    column<"LastName"_name , std::string>, 
    column<"DOB"_name  , date  > 
> Customer; 

Tuttavia, quando ho costruire questo tipo di costrutti a gcc, per esempio:

template <char... Chars> Name<Chars...> operator "" _name() { 
    return Name<Chars...>(); 
} 

auto a = 123_name; // OK 
auto b = "abc"_name; // Error 

ottengo il seguente errore:

…unable to find string literal operator ‘operator"" _name’ with ‘const char [4]’, ‘long unsigned int’ arguments 

da leggendo in giro, sto cercando di indovinare che la forma variadic-modello non è disponibile per UDL DERIVE d da stringhe letterali.

  1. È infatti il ​​caso che i valori letterali di stringa non possono essere risolti utilizzando il modulo modello variadic?
  2. Se sì, qualcuno ha qualche idea sul perché una tale forma utile di UDL è stata lasciata fuori dallo standard?
+0

Che cosa è esattamente utile creare un nuovo tipo per ogni tipo di letterale, che sarebbe completamente distinto l'uno dall'altro? –

+0

@NicolBolas: negli esempi mostrati, * vuoi * diversi valori letterali per avere tipi diversi. Inoltre, il tipo finale di un letterale non sarebbe necessariamente una ingenua concatenazione dei suoi personaggi. Ad esempio, "" freq:% g Hz "world" _fmt (44000) 'potrebbe risolversi in qualcosa come' Formatter ("freq:", "Hz") (44000) 'tramite metaprogrammazione –

+0

Ciò significherebbe anche che tu * non puoi * passarlo qualcosa che non è un numero, quindi non puoi passarlo a qualcosa che potrebbe usare 'operator <<' per convertire in un flusso, rimuovendo così la possibilità di personalizzare i tipi di dati. –

risposta

8

Hai ragione. stringhe letterali non possono essere utilizzati con la forma variadic modello (§2.14.8/5):

If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call of the form

operator "" X (str, len) 

ho mischiato tra le carte proposta (l'ultima delle quali ho trovato è stato N2750) e non riusciva a trovare una spiegazione per non consentire l'uso del modulo modello variadico.

+0

Potrebbe essere qualcosa di banale come sviluppo concorrente delle due funzionalità che impedivano l'utilizzo dell'altro? –

+0

@Matthieu M. Io non la penso così Non riesco a trovare prove che vengano sviluppati separatamente (sono sempre insieme nello stesso documento). Ad essere onesti, quando ho visto la forma variadica, la prima cosa che mi è venuta in mente era il tipo di idee che l'OP mostra nella risposta. Mi piacerebbe presumere che il comitato abbia visto qualche potenziale problema in questo. O quello o una supervisione molto fastidiosa. –

+3

Tutti i valori letterali definiti dall'utente che consentono l'uso della forma variadica sono limitati al set di caratteri sorgente di base (semplicemente perché la grammatica non consente nient'altro in ints o float). I valori letterali stringa non hanno questa limitazione, quindi con una codifica sorgente/esecuzione multibyte si hanno c-char nella stringa letterale che potrebbe non essere rappresentabile come singoli caratteri. Questo potrebbe avere qualcosa a che fare con la decisione di non consentire la forma variadica con stringhe letterali. – bames53

2

N3599, che consente questo, è stato implementato in gcc e clang.

template<class CharT, CharT... chars> 
int operator ""_suffix(){ 
    return 42; 
}