Funktor als Default-Argument



  • Warum geht das folgende nicht?

    #include <algorithm>
    
    template <typename T, typename PRED>
    void Test(T data, PRED pred = std::less<T>())
    {
    }
    
    int main()
    {
       Test(12);
       return 0;
    }
    

    Funktioniert nicht auf: VC8, VC6, Comeau mit untershciedlichen Fehlermeldungen (VC8 liefert noch die genaueste: typ des template-parameters konnte nicht hergeleitet werden)

    Mit einem zzweiten overload kann man das zwar fixen (die meisten STL-Impelementaitonen sheinen's ja so zu machen), aber ich bin neugierig ob der C++-Standard das verbietet, oder das nur ein Compiler-Problem ist.

    Dankeschön im voraus 🙂



  • Der Compiler muß ja erkennen, welche Version deiner Funktion er erzeugen muß - und dazu verwendet er die Typ-Informationen aus dem Aufruf. Bei Default-Argumenten kann er jedoch nichts aus dem Aufruf ermitteln (weil sie dort nicht da sind), deshalb muß er diese Typen vorher kennen.
    (davon abgesehen, daß dein Default-Parameter nicht mit jedem PRED-Typ verträglich sein dürfte)

    Die Lösung hast du ja schon genannt - die zusätzliche Überladung dürfte imho die beste Möglichkeit dafür sein:

    template<typename T>
    void Test(T data)
    {
      //vergleicht mit <
    }
    
    template<typename T,typename PRED>
    void Test(T data, PRED pred)
    {
      //vergleicht mit pred.operator()
    }
    


  • EDIT: war quatsch



  • CStoll schrieb:

    ...

    template<typename T>
    void Test(T data)
    {
      //vergleicht mit <
    }
    
    template<typename T,typename PRED>
    void Test(T data, PRED pred)
    {
      //vergleicht mit pred.operator()
    }
    

    Hi,

    geht nicht auch

    template<typename T,typename PRED = std::less<T> >
    void Test(T data, PRED pred)
    {}
    

    ?

    Gruß,

    Simon2.



  • Sicher geht das, bringt nur nichts - für die Funktion mußt du sowieso beide Parameter angeben und dann überschreibt die automatische Typdetektion den Dafaultwert für PRED.



  • g++ schrieb:

    default template arguments may not be used in function templates
    


  • Für default Template-Argumente kann man sich einen Funktor basteln:

    #include <functional>
    #include <iostream>
    
    template<template<typename> class TPred = std::less>
    struct tester
    {
        template<typename T>
        void operator()(T data)
        {
            std::cout << (TPred<T>()(data,15)?"ja":"nein") << std::endl;
        }
    };
    
    int main()
    {
       tester<> t;
       t(12);
    }
    


  • CStoll schrieb:

    Sicher geht das, bringt nur nichts - für die Funktion mußt du sowieso beide Parameter angeben und dann überschreibt die automatische Typdetektion den Dafaultwert für PRED.

    *hand-vor-die-stirn-klatsch*
    Stimmt !
    Hat ein bischen gedauert, bis ich's gepeilt habe, aber nun ist's mir klar.

    Danke,

    Simon2.


Anmelden zum Antworten