2011-11-23 6 views

risposta

18

iostreams proietterà la maggior parte dei puntatori su void * per la visualizzazione, ma non esiste alcuna conversione per i puntatori volatile. Come tale C++ ricade sul cast implicito su bool. Fusioni di void* in modo esplicito se si desidera stampare l'indirizzo:

std::cout << (void*)&clock; 
+0

Ho pensato che la conversione funzioni automaticamente? –

+0

Sì, c'è una conversione automatica. È solo che viene automaticamente convertito in 'bool', non' void * ', in quanto C++ non ha la conversione automatica in' void * 'per i puntatori (C fa, ma C++ richiede un cast esplicito) – bdonlan

+7

Oh! Johannes è anche umano! –

17

C'è un operator<< per const void*, ma non c'è operator<< per volatile void*, e la conversione implicita non rimuoverà volatile (non rimuoverà const o).

Come dice GMan, la qualifica di cv del tipo indicato dovrebbe essere irrilevante per l'attività di stampa di un indirizzo. Forse il sovraccarico definito in 27.7.3.6.2 dovrebbe essere operator<<(const volatile void* val);, non vedo immediatamente alcuno svantaggio. Ma non lo è.

#include <iostream> 

void foo(const void *a) { 
    std::cout << "pointer\n"; 
} 

void foo(bool a) { 
    std::cout << "bool\n"; 
} 

int main() { 
    volatile int x; 
    foo(&x); 
    std::cout << &x << "\n"; 
    int y; 
    foo(&y); 
    std::cout << &y << "\n"; 
    void foo(volatile void*); 
    foo(&x); 
} 

void foo(volatile void *a) { 
    std::cout << "now it's a pointer\n"; 
} 

uscita:

bool 
1 
pointer 
0x22cd28 
now it's a pointer 
+0

Picchiami letteralmente un secondo, urg :(.Per aggiungere: nella soluzione proposta da bdonlan, il cast di stile c come 'const_cast'. Ai fini della stampa, non è davvero una preoccupazione. – GManNickG

0

Questo perché non c'è sovraccarico per operator << che richiede un puntatore ad volatile, e non v'è alcuna conversione puntatore che potesse soddisfare esso.

Secondo lo standard C++,

per qualsiasi tipo T, puntatore T, puntatore const T e puntatore volatile T sono considerati tipi di parametri distinti, come lo sono riferimento T, riferimento const T, e riferimento a volatile T.

Operator << has no overload for pointers to non-static member, puntatori a, o puntatori funzione volatile, così il tentativo di uscita tali oggetti invoca conversione implicita a bool.