error C2664: 'std::make_pair': Konvertierung des Parameters 1 von 'physx::PxMaterial *' in 'physx::PxMaterial *&&' nicht



  • error C2664: 'std::make_pair': Konvertierung des Parameters 1 von 'physx::PxMaterial *' in 'physx::PxMaterial *&&' nicht möglich
    1> Ein lvalue kann nicht an einen rvalue-Verweis gebunden werden.

    std::unordered_map<PxMaterial*, PxMaterialTableIndex> materialIndicesMap;
    materialIndicesMap.insert(std::make_pair<PxMaterial*, PxMaterialTableIndex>(mat->second, index));
    

    VC++ 2012. Was ist falsch?



  • Mach mal die Template-Parameter weg.



  • *recht-geb*

    Template-Parameter für Funktionstemplates aus der Standardbibliothek angeben ist (fast immer) böse.

    Statt

    std::make_pair<PxMaterial*, PxMaterialTableIndex>(mat->second, index)
    

    kannst du

    std::make_pair(mat->second, index)
    

    oder

    std::pair<PxMaterial*, PxMaterialTableIndex>(mat->second, index)
    

    schreiben. Das ist ja gerade der Witz an std:make_pair, dass du die Typen nicht mit angeben musst! Deswegen gibt es std::make_pair!

    Ich möchte darauf hinweisen dass der resultierende Typ nicht map_typ::value_type ist, sondern höchstens dazu konvertierbar. Möchtest du diese Konvertierung sparen, kannst du auch

    std::pair<PxMaterial*const, PxMaterialTableIndex>(mat->second, index)
    

    schreiben.

    Oder du gehst ganz neue Wege:

    materialIndicesMap.emplace(mat->second, index);
    

    Warum funktioniert dein Kram unter C++11 nicht mehr? Weil die Standardbibliothek geändert wurde, und zwar von

    template<class T, class U>
    std::pair<T,U> make_pair(T a, U b);
    

    zu

    template<class T, class U>
    std::pair<?,?> make_pair(T && a, U && b);
    

    wobei && hier für "perfect forwarding" genutzt werden soll. Das hebelst du allerdings aus, wenn du die Template-Parameter selbst bestimmen willst und damit die Template Argument Deduction (TAD) umgehst. Im Wesentlichen ist das hier passiert:

    template<class T> void foo(T   v) {}
    template<class T> void bar(T&& r) {}
    
    int main()
    {
      int lvalue = 0;
      foo     (lvalue); // ok,  TAD -> T=int
      foo<int>(lvalue); // ok
      bar     (lvalue); // ok,  TAD -> T=int&
      bar<int>(lvalue); // NÖ! r wäre dann ja eine rvalue-Referenz und die
                        // kannst du nicht mit einem lvalue initialisieren.
    }
    

Anmelden zum Antworten