Template-Spezialisierung funktioniert nicht ...:



  • Hi Leuts,

    folgender Code

    template<class C>
    struct X {
    
        template<class T>
        struct x {
    	};
    
        };
    
    template<template <class> class F, class C>
    struct Y {    
        };
    
    template<class C>
    struct TEST {
        template<class T>
        struct test {
    	};
    
        template<class T1, class T2>
        struct test<Y<X<T1>::template x, T2> > {
    	typedef X<T1> test_type;
    	};
        };
    
    int main (int argc, char *argv[]) {
        TEST<double>::test< Y<X<int>::x, char> >::test_type x; 
        }
    

    Dies fuehrt zu einem fehler der Art

    /usr/bin/g++ -ansi -g -c -o main.o main.cpp
    main.cpp: In function ‘int main(int, char**)’:
    main.cpp:123: error: ‘test_type’ is not a member of ‘TEST<double>::test<Y<X<int>::x, char> >’

    ersetzt man hingegen die zweite Spezialisierung von test durch:

    template<template <class> class T0, class T2>
    struct test<Y <T0, T2> > {
       typedef X<T2> test_type;
       };
    

    gehts ... warum aber nicht bei der ersten variante ... kommt der compiler nicht mit dem template-template-parameter in der spezialisierung klar?

    Gruesse und Danke



  • EDIT: Ach neeee, kann nicht sein ... sorry.



  • Noe, daran liegt es nicht. typename einfuegen verursacht vielmehr noch einen weiteren Fahler:

    /usr/bin/g++ -ansi -g -c -o main.o main.cpp
    main.cpp:98: error: expected nested-name-specifier
    main.cpp:98: error: expected ‘;’ before ‘test_type’
    main.cpp: In function ‘int main(int, char**)’:
    main.cpp:123: error: ‘test_type’ is not a member of ‘TEST<double>::test<Y<X<int>::x, char> >’



  • LIBS schrieb:

    Noe, daran liegt es nicht. ...

    Hatte ich auch gerade gemerkt.

    Gruß,

    Simon2.


  • Mod

    Spezialisierungen können nur auf Namespace-Ebene deklariert und definiert werden, nicht innerhalb eines Klassetemplates. Also

    template<class C>
    struct TEST {
        template<class T>
        struct test {
        };
    
        };
    
    template<class C>
    template<class T1, class T2>
    struct TEST<C>::template test<Y<X<T1>::template x, T2> > {
    typedef X<T1> test_type;
    };
    

    oder so ähnlich



  • Hi camper ...

    1. Spezialisierungen können bei mir auch innerhalb eines Klassetemplates stehen -- kein problem eigentlich ...

    2. selbst wenn ich beide Spezialisierungen auf Namespace-Ebene deklariere habe ich den beschriebenen fehler ... 😞

    gruesse


  • Mod

    LIBS schrieb:

    Hi camper ...

    1. Spezialisierungen können bei mir auch innerhalb eines Klassetemplates stehen -- kein problem eigentlich ...

    2. selbst wenn ich beide Spezialisierungen auf Namespace-Ebene deklariere habe ich den beschriebenen fehler ... 😞

    gruesse

    Stimmt, war ich abwesend

    Ein Versuch mit dem Comeau C++ Compiler ist aufschlussreich:

    "ComeauTest.c", line 22: error: template parameter "T1" is not used in or cannot be
    deduced from the template argument list of class template
    "TEST<C>::test<Y<X<T1>::x, T2>>"
    template<class T1, class T2>
    ^

    Y<X<T1>::template x ist kein Kontext, in dem T1 deduziert werden kann (mit den jetzigen Regeln wäre es im Prinzip denkbar, spätestens wenn es template typedefs gibt, aber nicht mehr). Es fällt nicht unter die abschließende Liste in 14.8.2.4/9

    A template type argument T, a template template argument TT or a template non-type argument i can be
    deduced if P and A have one of the following forms:
    T
    cv-list T
    T*
    T&
    T[integer-constant]
    template-name<T> (where template-name refers to a class template)
    type()(T)
    T(
    )()
    T()(T)
    T type::

    type T::*
    T T::*
    T (type::)()
    type (T::
    )()
    type (type::)(T)
    type (T::
    )(T)
    T (type::)(T)
    T (T::
    )()
    T (T::*)(T)
    type[i]
    template-name<i> (where template-name refers to a class template)
    TT<T>
    TT<i>
    TT<>
    where (T) represents argument lists where at least one argument type contains a T, and () represents
    argument lists where no parameter contains a T. Similarly, <T> represents template argument lists where
    at least one argument contains a T, <i> represents template argument lists where at least one argument
    contains an i and <> represents template argument lists where no argument contains a T or an i.


Anmelden zum Antworten