2015-05-17 8 views
9

Lo standard definisce il tipo di un letterale stringa, in §2.13.5/8, come:Perché decltype su una stringa letterale non produce un tipo di matrice?

ordinaria stringhe e UTF-8 stringhe sono anche denominato strette stringhe letterali. Un letterale stringa stretto ha tipo "array of n const char", dove n è la dimensione della stringa come definito di seguito e ha durata di archiviazione statica (3.7).

Pertanto, ad esempio, "sss" dovrebbe avere un tipo di char const[4] (a meno che non lo sto leggendo in modo non corretto).

Ma questo semplice frammento:

std::cout << std::boolalpha << std::is_pointer<decltype("sss")>::value << '\n'; 
std::cout << std::boolalpha << std::is_array<decltype("sss")>::value; 

gives:

false 
false 

Che cosa mi manca?

+0

Altamente correlato: https://stackoverflow.com/q/15036281/3002139 –

risposta

18

letterali stringa sono lvalue ([expr.prim.general]/P1):

Un letterale è un'espressione primaria. Il suo tipo dipende dalla sua forma (2.13). Una stringa letterale è un lvalue; tutti gli altri letterali sono prvali.

decltype(expr) restituisce un Ivalue riferimento quando l'espressione expr è un'espressione lvalue ([dcl.type.simple]/p4):

Per un'espressione e, del tipo indicato con decltype (e) è definito come segue :

  • se e è un unparenthesized id-espressione o un unparenthesized accesso membro della classe (5.2.5), decltype (e) è il tipo di entità nominato da e. Se non esiste un'entità di questo tipo, o se si denomina una serie di funzioni sovraccaricate, il programma è mal formato;
  • altrimenti, se e è un xvalue, decltype (e) è T & &, dove T è il tipo di e;
  • altrimenti, se e è un lvalue, decltype (e) è T &, dove T è il tipo di e;
  • altrimenti, decltype (e) è il tipo di e.

stringhe letterali sono array di Nconst char, ma quello che stiamo vivendo è l'effetto di decltype. Quello che hai veramente è il tipo char const(&)[N], nonchar const[N].

semplicemente rimuovendo il riferimento dovrebbe darvi il comportamento che desiderare:

std::is_array<std::remove_reference_t<decltype("sss")>>::value; 
5

È necessario rimuovere il riferimento prima, dal momento che il tipo dedotta da decltype è const char (&)[N], non solo const char [N]:

std::cout << std::boolalpha << std::is_array< 
    typename std::remove_reference<decltype("sss")>::type 
>::value << '\n'; // true 
Problemi correlati