2015-05-17 12 views
9

standard określa typ łańcuch znaków na w §2.13.5/8, ponieważ:Dlaczego decltype w ciągu znaków literowych nie daje typu tablicy?

Zwykłe napisowych i UTF-8 napisowych są również określane jako wąskie napisowych. Wąskie wyrażenie literowe ma typ "tablica n const char", gdzie n jest rozmiarem łańcucha zdefiniowanego poniżej i ma statyczny czas przechowywania (3.7).

Dlatego, na przykład, "sss" powinna mieć typ char const[4] (chyba, że ​​czytam go nieprawidłowo).

Ale ten prosty fragment:

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

gives:

false 
false 

Czego mi brakuje?

+0

Wysoce powiązane: https://stackoverflow.com/q/15036281/3002139 –

Odpowiedz

18

łańcucha znaków są lwartościami ([expr.prim.general]/P1)

Dosłowne jest pierwotnym wyrażeniu. Jego rodzaj zależy od formy (2.13). Literał ciągu jest lwartością; wszystkie inne literały są wartościami.

decltype(expr) powraca lwartością odniesienie, gdy ekspresja expr jest wyrazem lwartość ([dcl.type.simple]/P4)

do wyrażenia E, typ oznaczona decltype (E) jest zdefiniowana jako następująco:

  • jeżeli e jest unparenthesized ID ekspresja lub unparenthesized dostępu członka klasy (5.2.5) decltype (e) rodzaj jednostki nazwie e. Jeśli nie ma takiego obiektu lub jeśli nadpisywane są funkcje o przeciążonych funkcjach, program jest źle sformułowany;
  • w przeciwnym razie, jeśli e jest wartością x, decltype (e) to T & &, gdzie T jest typem e;
  • w przeciwnym wypadku, jeśli e jest lwartością, decltype (e) to T &, gdzie T jest typem e;
  • inaczej, decltype (e) jest typem e.

literały łańcuchowe tablice Nconst char, ale to, czego doświadczamy, jest efektem decltype. To, co naprawdę masz, to typ: char const(&)[N], ,char const[N].

prostu usuwając odwołanie powinno dać zachowanie chec:

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

Trzeba usunąć odwołanie pierwszy, gdyż typ wywnioskować decltype jest const char (&)[N], nie tylko const char [N]:

std::cout << std::boolalpha << std::is_array< 
    typename std::remove_reference<decltype("sss")>::type 
>::value << '\n'; // true 
Powiązane problemy