Seite 1 von 1

Variadic Templates - Member function call

Verfasst: 11.10.2012, 14:59
von kristof
Hallo zusammen,

Clang konfrontiert mich hier gerade mit einer seltsamen Fehlermeldung. Ohne viele Worte zu verlieren, hier mal ein Beispiel:

Code: Alles auswählen

template<typename ...types>
struct foo {
    template<unsigned int i>
    void bar() { /* do something */ }
    template<unsigned int i>
    static void static_bar() { /* do something */ }
};

template<typename ...types>
void function() {
    foo<int, float> foo_test;
    foo_test.bar<42>(); // kein Problem
    
    foo<types...> foo_test2;
    foo_test2.bar<42>();
    //                ^ error: expected expression
    
    foo<int, float>::static_bar<42>(); // kein Problem
    foo<types...>::static_bar<42>();
    //                            ^ error: expected expression
}
Wie man sieht rufe ich eine Member Funktion der Struktur foo auf. Ob die Funktion statisch ist oder nicht macht dabei keinen Unterschied. Gebe ich die Template-Parameterliste explizit an, funktioniert alles wie erwartet. Versuche ich allerdings die Parameterliste von funktion zu verwenden, so meckert der Parser an der markierten Stelle.
Meine Frage ist nun: Ist das normal so? Oder ist das ein Problem von clang?
Danke schonmal!

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 15:22
von dot
Hm, sehr merkwürdig. Ich bin sicherlich kein Experte für variadic templates, aber ich würde hier fast einen Compilerbug vermuten; zumindest konnte ich im C++ Standard auf die Schnelle nichts finden, das so ein Konstrukt verbieten würde. Ändert sich was, wenn du vielleicht mal bar<42U> statt nur bar<42> schreibst?

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 15:43
von kristof
Danke für die schnelle Antwort.
dot hat geschrieben:Ändert sich was, wenn du vielleicht mal bar<42U> statt nur bar<42> schreibst?
Nein leider nicht.
Ich habe auch mal versucht der Member Funktion einen parameter zu verpassen. Dann bekomme ich eine andere Fehlermeldung. Das Ganze sieht dann so aus:

Code: Alles auswählen

template<typename ...types>
struct foo {
    template<unsigned int i>
    void bar(int dummy) { /* do something */ }
    template<unsigned int i>
    static void static_bar(int dummy) { /* do something */ }
};

template<typename ...types>
void function() {
    foo<int, float> foo_test;
    foo_test.bar<42>(0); // kein Problem
    
    foo<types...> foo_test2;
    foo_test2.bar<42>(0); // error: reference to non-static member function must be called
    
    foo<int, float>::static_bar<42>(0); // kein Problem
    foo<types...>::static_bar<42>(0); // error: reference to overloaded function could not be resolved; did you mean to call it?
}

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 15:51
von dot
Merkwürdig. Wie sieht es mit

Code: Alles auswählen

(foo_test2.bar<42>)(0);
(foo<types...>::static_bar<42>)(0);
aus!?

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 15:58
von kristof

Code: Alles auswählen

foo<types...> foo_test2;
(foo_test2.bar<42>)(0);
//                ^ error: expected expression
(foo<types...>::static_bar<42>)(0);
//                            ^ error: expected expression
Ich Vermute auch fast, dass es ein Compilerbug ist, zumal ich solche nichts sagenden Fehlermeldungen von Clang überhaupt nicht gewohnt bin.

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 16:27
von CodingCat
kristof hat geschrieben:Clang konfrontiert mich hier gerade mit einer seltsamen Fehlermeldung. Ohne viele Worte zu verlieren, hier mal ein Beispiel:

Code: Alles auswählen

template<typename ...types>
struct foo {
    template<unsigned int i>
    void bar() { /* do something */ }
    template<unsigned int i>
    static void static_bar() { /* do something */ }
};

template<typename ...types>
void function() {
    foo<int, float> foo_test;
    foo_test.bar<42>(); // kein Problem
    
    foo<types...> foo_test2;
    foo_test2.bar<42>();
    //                ^ error: expected expression
    
    foo<int, float>::static_bar<42>(); // kein Problem
    foo<types...>::static_bar<42>();
    //                            ^ error: expected expression
}
Mangels Unterstützung in MSVC habe ich keinerlei Erfahrung mit Variadic Templates, aber ich vermute, dass du einfach die abhängigen Templates als solche auszeichnen musst:

Code: Alles auswählen

template<typename ...types>
struct foo {
    template<unsigned int i>
    void bar() { /* do something */ }
    template<unsigned int i>
    static void static_bar() { /* do something */ }
};

template<typename ...types>
void function() {
    foo<int, float> foo_test;
    foo_test.bar<42>(); // kein Problem
    
    foo<types...> foo_test2;
    foo_test2.template bar<42>();
    //                ^ Template!
    
    foo<int, float>::static_bar<42>(); // kein Problem
    foo<types...>::template static_bar<42>();
    //                            ^ Template!
}

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 16:28
von dot
Ach verdammt stimmt, MSVC erzieht einen leider dazu, das immer zu vergessen...

Re: Variadic Templates - Member function call

Verfasst: 11.10.2012, 16:30
von kristof
Oh wow! Das war es tatsächlich. C++ hat doch immer neue Überraschungen für einen parat ;)
Vielen Dank für eure Hilfe.