2016-07-30 21 views
0

Ich habe einen Code, der std::to_string() ist eine Variable, deren Typ ein Vorlagenparameter ist. Angenommen, der Code ist:Machen std :: to_string Arbeit mit Void-Zeiger likes Operator <<?

template <typename T> 
std::string foo(const T& t) { 
    return std::string("I got ") + std::to_string(t); 
} 

Nun, manchmal muss dieser Parameter ein void * sein; und ich möchte die Adresse in der Zeichenfolge erhalten, z. "I got 0xdeadbeef". Kein Problem, oder? Ich sollte es genauso bekommen, als hätte ich std::cout << my_ptr, oder? ... Leider ist das nicht der Fall. Nun,

  • Ist es "legitim" für mich, den oben genannten Code zu verwenden, wie ich beschrieben habe?
  • Anders als in foo() auf der Verwendung eines Stroms beharren, gibt es etwas, als es besser zu machen void* ‚s zu überlasten std::to_string für (eine std::stringstream dort für die operator<< verwenden)?

Antwort

3
namespace my_to_str { 
    using std::to_string; 
    std::string to_string(void* ptr){ 
    // implement 
    } 
} 

Jetzt kann my_to_str::to_string mit Ihrem eigenen Satz von Überlastungen verlängert werden, wie void*.

-1

können Sie benutzerdefinierte operator+ für void * Fälle machen:

std::string operator+(const std::string &str, const void *vstr){ 
    return str + std::string(reinterpret_cast<const char *>(vstr)); 
} 
+0

Das void * ist keine Zeichenkette, ich kann es nicht als Zeichenkette ausgeben (ich würde eine Art 'as_hex()' Funktion brauchen, oder einen Stringstream benutzen); aber Ihr Vorschlag ist anders als das interessant. +1. – einpoklum

+0

Der 'reininterpret_cast' ist fast sicher falsch, und das wäre UB. – Barry

+0

@Barry wie? Wenn 'void * ptr' eine Null-terminierte Zeichenfolge enthält, ist es OK, in anderen Fällen wird UB sogar mit' char * ptr' und ohne Casting sein. – LibertyPaul

1

Sie können std::to_string() für void* nicht überlasten, so dass es strittig ist.

Aber Sie nicht haben zu verwenden std::to_string(). Sie könnten Ihre eigenen implementieren, dass eine stringstream fällt gerade zurück zu verwenden:

namespace N { 
    template <class T> 
    auto to_string(T const& val, int) 
     -> decltype(std::to_string(val)) 
    { 
     return std::to_string(val); 
    } 

    template <class T> 
    std::string to_string(T const& val, ...) 
    { 
     std::ostringstream oss; 
     oss << val; 
     return val.str(); 
    } 

    template <class T> 
    std::string to_string(T const& val) { 
     return to_string(val, 0); 
    } 
} 

Und das hat ermöglichen Überlastung N::to_string() mit dem, was Besonderheiten Sie möchten (zB wenn Sie N::to_string(void*) wollen etwas Besonderes tun, fügen Sie einfach einen weiteren Überlastung).

+0

Können Sie diesen Trick mit der 0 erklären? Ich meine, warum zwei Überladungen nicht genug sind? Auch seit wann kannst du 0 als Parameter haben? – einpoklum

+0

@einpoklum Sollte 'int' sein. Die Umwandlung in "int" wird der Umwandlung in "..." vorgezogen – Barry