Memberfunktionstemplate in einem spezialisierten Klassentemplate



  • Guten morgen,

    ich habe mich gerade verknotet. Soll vorkommen, wenn man zuviele Templates hat 🙂

    Gegeben sei folgendes Klassentemplate

    template<typename A, typename B>
    class Foo
    {
    public:
        // ctor, dtor weggelassen
    
        template<typename T, typename U>
        int bar(const T& value, const B& meta, const U&);
    
    };
    

    Angenommen, für meinen Anwendungsfall stehen A und B fest

    typedef Foo<MyA, MyB> MyFoo;
    

    wie implementiere ich jetzt für das gegebene A und B das generische Template von bar()?

    template<typename T, typename U>
    int MyFoo::bar<T, U>(const T& value, const MyB& meta, const U&)
    {
        return doFancyStuff();
    }
    

    bzw eine totale Spezialisierung von MyFoo::bar ?

    template<>
    int MyFoo::bar<string, int>(const string& value, const MyB& meta, const int&)
    {
        return doSpecialStuff();
    }
    

    Gcc 4.5.0 erzählt mir zu allgemeinen Funktionsdefinition:

    error: template-id ‘bar<T, U>’ in declaration of primary template
    error: new declaration ‘int Foo<MyA, MyB>::bar(const T&, const MyB&, const U&)’
    error: ambiguates old declaration ‘int Foo<A, B>::bar(const T&, const B&, const U&) [with T = T, U = U, A = MyA, B = MyB]’
    

    und zur Spezialisierung:

    error: template-id ‘bar<string, int>’ for ‘int Foo<MyA, MyB>::bar(const string&, const MyB&, const int&)’ does not match any template declaration
    note: saw 1 ‘template<>’, need 2 for specializing a member function template
    

    Ich hab zwar schon oft Klassen spezialisiert, ich hab auch schon oft Funktionen spezialisiert, aber noch nie template-Memberfunktionen in Klassen, die selbst templates sind.

    Helft mir bitte auf die Sprünge 🙂

    Gruß,
    Philipp



  • Wer liest, was der Compiler sagt, ist klar im Vorteil 🙂

    So kompilierts:

    h-Datei

    template<typename A, typename B>
    class Foo
    {
    public:
        // ctor, dtor weggelassen
    
        template<typename T, typename U>
        int bar(const T& value, const B& meta, const U&);
    
    }; 
    
    typedef Foo<MyA, MyB> MyFoo; 
    
    template<>
    template<typename T, typename U>
    int MyFoo::bar(const T& value, const MyB& meta, const U&)
    {
        return doFancyStuff();
    } 
    
    template<>
    template<>
    int MyFoo::Bar<string, int>(const string& value, const MyB& meta, const int&);
    

    cpp-Datei

    template<>
    template<>
    int MyFoo::Bar<string, int>(const string& value, const MyB& meta, const int&)
    {
        return doSpecialStuff();
    }
    

    So schön das kompiliert, beim Linken gehts in die Hose: "undefined symbol: _ZN4XSPL15FooIN3SCS5MyAENS1_15MyBEE13barIiNS1_7AS_LONGEEEiRKT_RKS3_RKT0_"

    Diese Fehlermeldung hilft mir natürlich extrem weiter.

    Was mach ich falsch?



  • Ach, lernen im Selbsgespräch ist schon schön.

    So gehts:

    .h

    template<typename A, typename B>
    class Foo
    {
    public:
        // ctor, dtor weggelassen
    
        template<typename T, typename U>
        int bar(const T& value, const B& meta, const U&);
    
    };
    
    template<>
    class Foo<MyA, MyB> {
    
        template<typename T, typename U>
        int bar(const T& value, const MyB& meta, const U&)
        {
            return doFancyStuff();
        }
    };
    
    template<>
    int Foo<MyA, MyB>::Bar<string, int>(const string& value, const MyB& meta, const int&); 	
    
    typedef Foo<MyA, MyB> MyFoo;
    

    .cpp

    template<>
    int Foo<MyA, MyB>::Bar<string, int>(const string& value, const MyB& meta, const int&)
    {
        doSpecialStuff();
    }
    

    Klassentemplate spezialisieren statt typedeffen. Den Typedef gibts jetzt nur noch zur Bneutzer-Convenience.


Anmelden zum Antworten