2015-05-03 12 views
31

Może ktoś wyjaśnić wyjście z następującym programem:Rodzaj potrójnego wyrazu

#include <iostream> 
using namespace std; 

int main() 
{ 
    int test = 0; 
    cout << "First character " << '1' << endl; 
    cout << "Second character " << (test ? 3 : '1') << endl; 

    return 0; 
} 

wyjściowa:
Pierwszy znak 1
Druga postać 49

ale zarówno sprawozdanie printf powinien wydrukować ta sama linia.

+4

Jest to dobre pytanie, ale niezwiązane z efektami ubocznymi. – juanchopanza

Odpowiedz

34

Typ wyrażenia '1' to char.

Typ wyrażenia (test ? 3 : '1') wynosi co najmniej int (lub jego niepodpisaną wersję, ewentualnie jest to std::common_type_t<int, char>).

Dlatego te dwie inwokacje operatora << wybierają różne przeciążenia: Pierwszy z nich wypisuje znak w niezmienionej postaci, drugi formatuje liczbę całkowitą jako jej dziesiętną reprezentację. (Całka wartość znaku '1' jest zdefiniowana przez zbiór znaków bazowej.)

5

cout wyświetli wartość (test ? 3 : '1') wypowiedzi po wyciągania odpowiednią <<operator. W tym przypadku jest to int, można to sprawdzić za pomocą ładne sztuczki że Scott Meyers rozmnażane Jego newest book:

template < typename T > class TD; // Type Displayer 
int main() 
{ 
    int test = 0; 
    TD<decltype((test ? 3 : '1'))> xType; 

    return 0; 
} 

ten generuje błąd, który również daje informację o rodzaju wyrażenia:

main.cpp:6:34: error: aggregate 'TD<int> xType' has incomplete type and cannot be defined TD xType;

która jest int. I static_cast<int>('1') jest 49.

+2

'static_cast ('1')' ma 49 na wielu systemach, ale nie jest wymagane. Istnieją systemy, w których tak nie jest. –

+0

IIIRC, literały znaków/znaki nie muszą być w formacie ASCII, chyba że określono format (np. 'U8'). Powinieneś też o to zapytać. – edmz