Template Parameter von tr1::result_of<>



  • Hallo Leute,

    ich habe eine Anwendung von tr1::result_of<> codiert, komme aber beim Template Parameter zu keiner compilierfähigen Lösung. Mein auf das notwendigste reduzierter Code ist der folgende:

    #include <boost/tr1/functional.hpp> // result_of
    
    struct A {};
    struct B {};
    struct C {};
    C func( A, B )
    {
        return C();
    }
    
    template< typename T1, typename T2 >
    typename std::tr1::result_of< func( T1, T2 ) >::type // <-- hier ist was falsch
        call_f( T1 x1, T2 x2 )
    {
        return func( x1, x2 );
    }
    
    int main()
    {
        A a;
        B b;
        C c = func( a, b );
        C malSehn = call_f( a, b );
        return 0;
    }
    

    Bei der Deklaration des Returnwerts von call_f meckert der Compiler "error C2275: 'T1' : illegal use of this type as an expression". Ich nutze VC8 (alias Visual Studio 2005) mit dem aktuellen Service Pack.
    Beim ursprünglichen Problem war func == operator*; aber wenn ich wüsste, wie das obige funktioniert, wäre mir schon geholfen.
    Hat einer 'ne Idee wie man den Funktionstyp richtig angibt?

    :xmas2: Werner



  • Hmm liegt es vllt daran, dass du einen Typ an deine func übergibst und keine Variable?



  • Natürlich ein Typ; was den sonst ?? Das ist schließlich ein Template Parameter

    😕 Werner



  • Höö? Bin ich gerade blind, oder stimmt das nicht was du gesagt hast:

    C func( A, B )
    {
        return C();
    }
    

    ==

    C func(A param1, B param2)
    {
        return C();
    }
    

    ... demnach kann func wenig mit einem "type as an expression" anfangen ... !?

    template <typename T1, typename T2>
    func( T1, T2 )
    

    ?



  • (D)Evil schrieb:

    template <typename T1, typename T2>
    func( T1, T2 )
    

    ?

    .. nein Du bist nicht blind 😉
    Mein Gedanke ist, dass der Ausdruck func( T1, T2 ) der Typ einer Funktion mit dem Namen 'func' sein soll - der Name steht fest - und den zwei Typen T1 und T2. Der Compiler sieht das anders; d.h diese Syntax ist wohl falsch - das ist ja meine Frage.
    Ich kann den Funktionsnamen als drittes Argument des Templates call_f angeben, das möchte ich aber nicht, den der steht schon fest und ich will/kann den nicht als Parameter mit angeben, da - wie schon erwähnt - im Original-Problem es sich um den operator* handelt.

    :xmas2: Werner



  • Wenn ich das richtig aus der Doku lese, muss bei

    result_of<F(T1, T2, ..., TN)>::type
    

    F ein Funktionszeigertyp sein. Dein func ist dagegen ein Funktionszeiger.

    Dementsprechend funktioniert bei mir folgendes:

    #include <boost/tr1/functional.hpp> // result_of
    
    struct A {};
    struct B {};
    struct C {};
    C func( A, B )
    {
        return C();
    }
    typedef C (*funcptr)( A, B );
    
    template< typename T1, typename T2 >
    typename std::tr1::result_of< funcptr( T1, T2 ) >::type // <-- hier ist was korrigiert
        call_f( T1 x1, T2 x2 )
    {
        return func( x1, x2 );
    }
    
    int main()
    {
        A a;
        B b;
        C c = func( a, b );
        C malSehn = call_f( a, b );
        return 0;
    }
    

    :xmas1:



  • Danke michba,

    Leider löst das mein Problem nicht, da A und B nicht die einzigen Typen sind, für die das Template eingesetzt werden soll. Und sobald ich ein zweites Tripel von Typen habe

    typedef C2 (*funcptr)( A2, B2 );
    

    Liefert mir der Compiler "'funcptr' : redefinition; different basic types", und zwar mit Recht.

    Ich habe mein Problem vielleicht zu sehr vereinfacht. Etwas konkreter beschrieben möchte ich sowas:

    #include <complex>
    
    template< typename T >
    struct A 
    {
        explicit A( const T& x = T() ) : m_x( x ) {}
        T m_x;
    };
    
    // --  diesen Block würde ich mir gern ersparen
    template< typename T1, typename T2 > 
    struct result_of_multiplication;
    
    template<>
    struct result_of_multiplication< double, std::complex< double > >
    {
        typedef std::complex< double > type;
    };
    template<>
    struct result_of_multiplication< std::complex< double >, double >
    {
        typedef std::complex< double > type;
    };
    // --  Block Ende
    
    template< typename T1, typename T2 >
    A< typename result_of_multiplication< T1, T2 >::type >
        operator*( const A< T1 >& x1, const T2& x2 )
    {
        return A< typename result_of_multiplication< T1, T2 >::type >( x1.m_x * x2 );
    }
    
    int main()
    {
        using namespace std;
        A< complex< double > > a1;
        A< double > a2;
        A< complex< double > > erg;
        complex< double > cplx( 0, 1 );
    
        erg = a1 * 2.01;    // A< complex > * double -> A< complex >
        erg = a2 * cplx;    // A< double > * complex -> A< complex >
        return 0;
    }
    

    Also der Ergebnistyp E von A<E> = A<T1> * T2 soll immer der sein, der sich auch aus der Multiplikation E = T1 * T2 ergibt. Ich hatte angenommen, tr1::result_of kann mir den generieren, fragt sich nur wie.

    :xmas2: Werner


Anmelden zum Antworten