Verschachtelte Klassen in Templateklassen



  • Hallo!
    Ich beschäftige mich gerade mit Templates und habe folgendes versucht:

    template <typename T>
    class A {
    public:
        class SubType { };
    
    };
    
    template <typename U>
    void foo(typename A<U>::SubType& t);
    
    int main()
    {
        A<int>::SubType t;
    
        foo(t);
        return 0;
    }
    
    template <typename U>
    void foo(typename A<U>::SubType& t)
    {
    ...
    }
    

    Der Intel C++ Compiler gibt folgendes aus:
    error: no instance of function template "foo" matches the argument list
    argument types are: (A<int>::SubType)
    foo(t);
    ^

    G++ liefert folgendes:
    error: no matching function for call to ‘foo(A<int>::SubType&)’

    Wenn ich "typename" in der Funktionssignatur weglasse, dann meint der Intel C++ Compiler, dass foo weder eine Funktion noch ein statisches Member sei.

    Was ist das Problem?

    Grüße,
    Kevin


  • Mod

    XtrmK3v0r schrieb:

    Was ist das Problem?

    A<U>::SubType ist kein Kontext, in dem U deduziert werden kann. Du müsstest U explizit mit angeben, also

    foo<int>(t);
    

    Kleines (sinnfreies) Beispiel, um den Grund zu illustrieren:

    template <typename T> struct Foo {
        typedef int type;
    };
    template <typename T> void foo(typename Foo<T>::type);
    
    template <typename T> struct Bar {
        typedef T type;
    };
    template <> struct Bar<void> {
        typedef int type;
    };
    template <typename T> void bar(typename Bar<T>::type);
    
    int main()
    {
         int x;
         foo(x); // T könnte alles mögliche sein
         bar(x); // könnte int oder void sein
    }
    

    Um überhaupt herauszubekommen, ob ein bestimmtes Templateargument passt, müsst der Compiler alle Argumente ausprobieren und das zugehörige Template instantiieren. Das geht nat. nicht. Übrigens ist auch schon die Tatsache, dass typenmae benutzt werden muss, ein starker Hinweis darauf, dass der Kontext nicht deduzierbar ist.



  • Ah okay vielen Dank! Das macht natürlich Sinn. Der Compiler kann ja gar nicht wissen welche exakte Klasse zu instanziieren ist. Du meintest sicherlich in den Zeilen 6 und 9 'Bar' anstatt 'Foo' oder?!

    Grüße,
    Kevin


  • Mod

    XtrmK3v0r schrieb:

    Du meintest sicherlich in den Zeilen 6 und 9 'Bar' anstatt 'Foo' oder?!

    ja.


Log in to reply