2016-04-16 23 views
1

Sagen wir, ich habe eine Klasse A umwandeln, die Umwandlungimplizit std :: shared_ptr auf einen Typ

struct A { 
    int val = 42; 
    operator int() const { 
    return val; 
} 

so kann ich es wie folgt verwenden, um int spezifiziert:

A a; 
int a_int = a; 

Aber was, wenn ich wollen freigegebenen Zeiger auf die Klasse verwenden:

auto a_ptr = std::shared_ptr<A>(new A); 
int a_int = a_ptr; // ??? 

Genau wie die Variable mit Typ A implizit in int umgewandelt wurde ich das gleiche tun wollen mit einem intelligenten Zeiger. Wie kann ich das erreichen?

UPDATE

Es tut mir Leid vielleicht falsch, fragte ich. Der eigentliche Deal ist ein bisschen komplizierter. Ich benutze QVariant, um std :: shared_ptr zu halten. für jetzt habe ich eine Hilfsfunktion zu tun, dass:

QVariant & operator<< (QVariant& v, const std::shared_ptr<A> & aPtr); 

Wenn ich brauche, um meine Zeiger auf QVariant platzieren ich dies:

QVariant variant = QVariant() << a_ptr; 

Aber ich möchte es automatisch tun, so etwas wie dieses :

QVariant variant = a_ptr; 
+3

Tu das nicht. Schreib einfach '* a_ptr'. –

+0

Die neuen Smart Pointer funktionieren genau wie normale Pointer, die Dinge wie Dereferenzierung enthalten. –

+1

Überlastung der Betreiber in den meisten Fällen ist schlechtes Engineering. Bitte vermeide das. –

Antwort

0

Seine ganz einfach, verwenden Dereferenzierungsoperator:

int a_int = *a_ptr; // ??? 
      ^~~~ 

[Bearbeiten]

zu machen:

QVariant variant = a_ptr; 

Arbeit, würden Sie hinzufügen müssen, um QVariant Konstruktor Bezug zu akzeptieren kopieren Shared_ptr. Und das kannst du nicht tun. Eine solche Anweisung heißt Copy Initialization, der erste Compiler versucht die Konvertierung von a_ptr zu QVariant und wenn er verfügbar ist, wird der Kopierkonstruktor von QVariant mit dem konvertierten a_ptr aufgerufen. Das Problem ist, dass selbst wenn Sie a_ptr dereferenzieren, zwei benutzerdefinierte Konvertierungen benötigt werden.

Sie können immer noch eine Besetzung wie hier hinzufügen:

QVariant variant = static_cast<int>(*a_ptr); 
+0

Ich kann keine Instanz von A in QVariant halten. Es ist zu groß. Ich muss dort einen Zeiger platzieren. Immer wenn es eine Anweisung gibt, die QVariant als Parameter erwartet, möchte ich sie in QVariant konvertieren (und diese Konvertierung nach Bedarf angeben, in einigen Fällen kann es ziemlich kompliziert sein). –

+0

Nun, das ändert die Dinge, von dem, was ich sehe, kann QVariant void * enthalten, also vielleicht a_ptr.get() in void * umwandeln und QVariant zuweisen? – marcinj

0

Sie es versucht haben?
std::shared_ptr hat die operator* und es funktioniert wie man es erwarten kann: verwenden Sie es.

#include <memory> 

struct A { 
    int val = 42; 
    operator int() const { 
     return val; 
    } 
}; 

int main() { 
    auto ptr = std::make_shared<A>(); 
    int v = *ptr; 
} 
0

Genau wie die Variablen mit Typ A wurde implizit in int umgewandelt ich das gleiche mit einem intelligenten Zeiger tun will.

Nein, Sie denken, Sie tun, aber Sie wirklich nicht.

Wie kann ich das erreichen?

Sie können nicht, und das ist eine gute Sache.

(vorausschauend) Irgendwie herum?

Wickeln Sie den gemeinsamen Zeiger in ein Objekt, wie folgt aus:

#include <memory> 

template<class T> 
struct shared_reference 
{ 
    shared_reference(std::shared_ptr<T> pt) : _pt(std::move(pt)) {} 

    operator T&() { 
    return *_pt; 
    } 

    operator const T&() const { 
    return *_pt; 
    } 

    std::shared_ptr<T> _pt; 
}; 
Verwandte Themen