Verschachtelte Template-Argumente



  • Hi!

    Ich mache so selten was komplizierteres mit Templates und weiß grad nicht weiter, Google und Boardsuche haben mir auch nichts gebracht. Und zwar würde ich für eine Template-Funktion gerne einen Template-Typ angeben, der aber selbst eine Templateklasse mit einem bestimmten Template-Parameter sein muss.
    So in etwa meine ich das:

    template< typename Container<int> >
    void bla( const Container& x, const Container& y )  { ... }
    

    Ich meine mich zu erinnern, dass das vielleicht gar nicht ging? Mag mir jemand Klarheit verschaffen?


  • Mod

    So etwas ist für eine partielle Spezialisierung möglich, die fällt bei Funktionstemplates natürlich aus. Dort können wir aber auf Typdeduktion aus dem Argument ausweichen:

    template< template <typename> class TT >
    void bla( const TT<int>& x, const TT<int>& y )  { ... }
    


  • Cool, das sieht gut aus 👍 Nur hab ich keine Ahnung, wie ich die Funktion dann aufrufen kann 😃

    Der Compiler (von MSVC++ 2005) meckert bei

    int main()
    {
    	std::vector<int> x, y;
    	bla( x, y );
    }
    

    , aber auch bei bla<std::vector>( x, y ); oder bla<std::vector<int> >( x, y ); .

    Der Online-Comeau (http://www.comeaucomputing.com/tryitout/) mag's auch nicht 😕

    edit: Kacke, scheint am Default-Allocator vom vector zu liegen.. Aber danke dir trotzdem für die schnelle Lösung camper! (Ich glaube bei der partiellen Spezialisierung hattest du mir auch schon mal weitergeholfen..)



  • Dafür reicht aber auch:

    template< typename TT >
    void bla( const TT& x, const TT& y )  {  }
    


  • 😕

    So wie du die Funktion aufrufst, ist mir nicht ganz klar warum da eine einfaches Template nicht ausreichend sein soll.



  • war zu langsam 🙂


  • Mod

    Bei Templates mit Defaultargument funktioniert das so tatsächlich nicht. Es gibt natürlich auch andere Mittel und Wege.

    template<typename T>
    typename enable_if<is_same<typename T::value_type,int> >::type void bla( const T& x, const T& y );
    


  • David_pb schrieb:

    Dafür reicht aber auch:

    template< typename TT >
    void bla( const TT& x, const TT& y )  {  }
    

    Schon, aber ich finde es schon immer schön, wenn's aus der Signatur halbwegs deutlich wird, was man übergeben muss.

    camper schrieb:

    Bei Templates mit Defaultargument funktioniert das so tatsächlich nicht. Es gibt natürlich auch andere Mittel und Wege.

    template<typename T>
    typename enable_if<is_same<typename T::value_type,int> >::type void bla( const T& x, const T& y );
    

    Sieht interessant aus, kompiliert aber leider nich ('boost::enable_if<boost::is_same<T::value_type,int>>::type' gefolgt von 'void' unzulässig). Ich würd auch selber mit enable_if und is_same rumspielen, muss mich da aber erstmal einarbeiten.



  • enable_if ist eigentlich unglaublich simpel:
    Ist das erste Argument wahr, dann ist typename enable_if<C, T>::type == T.
    Ansonsten kommt es zu einem "Substitution Failure", was diese Spezialisierung der Funktion deaktiviert.
    camper meinte wohl

    template<typename T>
    typename enable_if<is_same<typename T::value_type,int>, void>::type bla( const T& x, const T& y );
    


  • Krasse Sache. *staun*!


  • Mod

    Da hatte ich beim C&P+Edit versehentlich vergessen, das void wegzumachen. Das ist auch Defaultargument von enable_if, eigentlich wollte ich

    template<typename T>
    typename enable_if<is_same<typename T::value_type,int> >::type bla( const T& x, const T& y );
    

    Obwohl es in diesem Falle vielleicht sogar besser explizit dastehen sollte.



  • Wegen der Lesbarkeit? 😃


Anmelden zum Antworten