Adresse überladener Funktionen



  • Hallo Forum,

    ich habe zwei (lokale) Convert-Funktionen die zwei Datentypen ineinander konvertieren:

    Foo Convert(const Bar&);
    Bar Convert(const Foo&);
    

    Wenn ich nun diese Funktionen beispielsweise in einem der Standardalgorithmen verwenden möchte

    std::transform(fooVec.begin(), fooVec.end(), barVec.begin(), Convert);
    

    beschwert sich der Compiler über die Mehrdeutigkeit des Namens bzw. dass er das Template-Argument für die aufzurufende Funktion nicht ableiten kann:

    error C2783: '_OutIt std::transform(_InIt,_InIt,_OutIt,_Fn)': could not deduce template argument for '_Fn'

    Ich habe mir mit einem cast beholfen, bin mir aber unsicher, ob das tatsächlich das Mittel der Wahl ist.

    std::transform(fooVec.begin(), fooVec.end(), barVec.begin(), static_cast<Foo (*)(const Bar&)>(Convert));
    

    Könnte mir das bitte jemand bestätigen bzw. bessere Möglichkeiten aufzeigen?

    Vielen Dank vorab!



  • Hallo,

    ich denke, das ist schon in Ordnung so.
    Alternativ könntest du ein lambda nutzen.

    std::transform(fooVec.begin(), fooVec.end(), barVec.begin(), 
      [](const Bar& b)
      { return Convert(b);}
    );
    


  • Vielen Dank für die Rückmeldung!

    Den Funktionsaufruf nochmal in ein Lambda zu verpacken funktioniert, hat für mich aber ein wenig Workaround-Charakter. Man gibt im Funktionsparameter des Lambda explizit den erforderlichen Typ an (oder lässt ihn deduzieren) und erzwingt dadurch den korrekten Convert-Aufruf innerhalb.

    Interessant finde ich, dass die Typdeduktion für auto im folgenden Fall funktioniert (habe ich erwartet)

    std::transform(fooVec.begin(), fooVec.end(), barVec.begin(), [](const auto& b)
    {
        return Convert(b);
    });
    

    aber die automatische Deduktion der erforderlichen Convert-Funktion eben nicht (hätte ich mir erhofft 🙂 ).



  • Grund Kurz und Knapp: Weil template argument deduction nicht stattfindet, wenn der Parameter eine überladene Funktion ist.



  • Du kannst auch einfach in den gegebenen Funktionspointer casten, dann hast du die Mehrdeutigkeit aufgelöst.



  • UnaryFunction schrieb:

    std::transform(fooVec.begin(), fooVec.end(), barVec.begin(), static_cast<Foo (*)(const Bar&)>(Convert));
    

    stateofmind schrieb:

    Du kannst auch einfach in den gegebenen Funktionspointer casten, dann hast du die Mehrdeutigkeit aufgelöst.

    *Hust*



  • Gesundheit. Taschentuch?


Anmelden zum Antworten