Reference auf Objekt im shared_ptr



  • Hallo,
    ich habe mal wieder ein Problem.

    Ich habe einen std::vector mit std::shared_ptr<TcpSocket>. Wenn ich nun einen ptr aus dem Vector nehme und an eine Funktion übergeben will, die eine Reference auf den TcpSocket darin haben will, bekomme ich eine Fehlermeldung, die ich nicht zu lösen weiß.
    Ich habe schon mehrere Varianten ausprobiert mit const_cast und Zwischenspeichern des rohen Pointers, das hat aber alles nicht funktioniert.

    Fehler:
    error C2664: 'sf::TcpSocket::TcpSocket(const sf::TcpSocket &)': Konvertierung des Parameters 1 von 'sf::TcpSocket *' in 'const sf::TcpSocket &' nicht möglich

    connected_clients.push_back(std::make_shared<TcpSocket>(new TcpSocket()));
    listener.accept(*connected_clients.back().get());
    


  • connected_clients.push_back(std::make_shared<TcpSocket>(new TcpSocket()));
    listener.accept(*(connected_clients.back()->get()));
    

    Manchmal hilft es, das Hirn anzuschmeissen ...


  • Mod

    *connected_clients.back().get()
    

    Das get() ist hierbei überflüssig, der überladene Dereferenzierungs-Operator tut es auch.

    Normalerweise kann so eine Fehlermeldung nicht bei dem gezeigten Code entstehen.

    Edit: Habe ich was missverstanden, oder was zeigt manni da?


  • Mod

    Manchmal hilft es, das Hirn anzuschmeissen ...

    Das gilt wohl in erster Linie für dich? Schon deswegen, weil sowohl der Punkt- als auch der Pfeil-Operator stärker binden als der Dereferenzierungs-operator. Daher sind etwaige Klammern natürlich überflüssig. Außerdem sehe ich nicht, woraus du schließt, dass TcpSocket eine Memberfunktion namens get hat.

    Edit: Das kommt laut Fehlermeldung aus SFML: sf::TcpSocket hat keine solche Memberfunktion.



  • Das get() bezieht sich auf den shared_ptr, das habe ich nur eingefügt, um sicher zu gehen, dass ich wirklich den enthaltenden Pointer vor mir habe.

    Hinter der eigentlichen Fehlermeldung ist noch ein etwas längerer Teil, der wahrscheinlich dazugehört, aber für mich nicht aussagekräftig ist, vielleicht kann da ja noch jemand etwas mit anfangen.

    c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(873): error C2664: 'sf::TcpSocket::TcpSocket(const sf::TcpSocket &)': Konvertierung des Parameters 1 von 'sf::TcpSocket *' in 'const sf::TcpSocket &' nicht möglich
    1> Ursache: Konvertierung von 'sf::TcpSocket *' in 'const sf::TcpSocket' nicht möglich
    1> Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Überladungsauflösung des Konstruktors ist mehrdeutig
    1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(972): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "std::_Ref_count_obj<_Ty>::_Ref_count_objsf::TcpSocket(_V0_t &&)".
    1> with
    1> [
    1> _Ty=sf::TcpSocket,
    1> _V0_t=sf::TcpSocket *
    1> ]
    1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(972): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "std::_Ref_count_obj<_Ty>::_Ref_count_objsf::TcpSocket(_V0_t &&)".
    1> with
    1> [
    1> _Ty=sf::TcpSocket,
    1> _V0_t=sf::TcpSocket *
    1> ]
    1> d:\daten\projekte\server-to-be-determined\server-to-be-determined\clientmanager.cpp(21): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "std::shared_ptr<_Ty> std::make_sharedsf::TcpSocket,sf::TcpSocket*(_V0_t &&)".
    1> with
    1> [
    1> _Ty=sf::TcpSocket,
    1> _V0_t=sf::TcpSocket *
    1> ]


  • Mod

    Ich bin verdammt blind: Der Fehler befindet sich in der Zeile mit dem push_back . Die habe ich mir gar nicht angeschaut.

    Ändere das einfach ab zu

    connected_clients.emplace_back( std::make_shared<TcpSocket>() );
    

    , dann kompiliert es.



  • Danke, es funktionert,
    kannst du aber vielleicht erklären, wieso das jetzt geht bzw. einen Link zu einem Artikel oderso schicken?
    Ich habe mir zwar die Docu angeschaut, aber so wie ich das verstehe, war das jetzt nur eine "Umformulierung" des Quellcodes, wobei der Inhalt enthalten bleibt.


  • Mod

    make_shared nimmt nur die Argumente für den Konstruktor, den new -Aufruf macht die Funktion schon selbst.



  • Arcoth schrieb:

    Ändere das einfach ab zu

    connected_clients.emplace_back( std::make_shared<TcpSocket>() );
    

    , dann kompiliert es.

    Wobei emplace_back() hier nichts bringt, du könntest auch push_back() nehmen.

    Ich persönlich behalte mir Emplacement für die Fälle vor, wo ich direkt Konstruktorargumente (aber nicht für den Kopierkonstruktor) übergebe. Das macht den Code etwas aussagekräftiger.


  • Mod

    @Nexus: Mir ist gerade erst aufgefallen, dass alle push_back s natürlich auch moven. Hätte ich mir selbst denken können.



  • Ok, ich glaube ich habe es verstanden 🙂

    Danke


Log in to reply