Anfänger benötigt Hilfe bei Templates



  • @KlammerKarl sagte in Anfänger benötigt Hilfe bei Templates:

    U ist ja entweder ein int, oder ein char* und das müsste ich unterscheiden. Ist da das typeid das Mittel der Wahl?

    Inwiefern musst du das unterscheiden? Zum Serialisieren? Ich würde das über Spezialisierung und ein Hilfstemplate, evtl. trait-artig machen.



  • @KlammerKarl sagte in Anfänger benötigt Hilfe bei Templates:

    Oder wie würde ich spezialisierte Templates für int und für char* erstellen?

    Why Not Specialize Function Templates?



  • @Mechanics: Ja ich muss das unterscheiden für die Serialisierung. Die Lib die ich dafür verwende benötigt einen andere Funktion, wenn man ein Attribut vom Typ int hinzufügen möchte.

    @Swordfish: Ok, also müsste ich je eine Überladung für die rekursive Funktion und eine für die endgültige Funktion erstellen?
    So in etwa?

    //Rekursionsende
    template<typename U>
    int addAttribute( const char* name, int val )
    {
    
    	return 1;
    }
    
    template<typename U>
    int addAttribute( const char* name, char* val )
    {
    
    	return 1;
    }
    
    //rekursiv
    template <typename U, typename... Args>
    int addAttribute(const char* name, int val, Args... args)
    {
    	//t ist abgetrenter Parameter 
    	// u ist 2.
    
    	const char *bla = typeid(val).name();
    
    	return addAttribute( args... );
    }
    
    template <typename U, typename... Args>
    int addAttribute(const char* name, char* val, Args... args)
    {
    	//t ist abgetrenter Parameter 
    	// u ist 2.
    
    	const char *bla = typeid(val).name();
    
    	return addAttribute( args... );
    }
    


  • Warum so kompliziert? Du brauchst am Ende ja keine Templates mehr, sondern nur überladene Funktionen. Das hatte ich mit Hilfstemplate gemeint, aber mit überladenen Funktionen gehts hier noch einfacher.



  • @Mechanics sagte in Anfänger benötigt Hilfe bei Templates:

    Warum so kompliziert? Du brauchst am Ende ja keine Templates mehr, sondern nur überladene Funktionen. Das hatte ich mit Hilfstemplate gemeint, aber mit überladenen Funktionen gehts hier noch einfacher.

    Hmm ok, dann kann ich dir nicht folgen.
    Die Anzahl an Parametern ist ja dynamisch. Ich dachte da gibt es nur den Weg über die paked Parameters in templates.
    Gibt es noch eine andere Möglichkeit?
    Wie gesagt, ich bin noch recht neu in C++.



  • Deine letzte Funktion, die nur noch einen Parameter hat, muss den Wert ja auch speichern. Ok, die heißt schon addAttribute, vielleicht war das verwirrend. Dann ruf in der doch einfach "storeAttribute" oder so auf, und das ist keine template Funktion mehr.



  • So, kam nun zum testen:

    #include "stdafx.h"
    #include <iostream>
    
    #include <typeinfo>
    
    using namespace std;
    
    
    //Rekursionsende
    int addAttribute(const char* name, int val)
    {
    
    	return 1;
    }
    
    int addAttribute(const char* name, char* val)
    {
    
    	return 1;
    }
    
    //rekursiv
    template <typename... Args>
    int addAttribute(const char* name, int val, Args... args)
    {
    	//t ist abgetrenter Parameter 
    	// u ist 2.
    
    	const char *bla = typeid(val).name();
    
    	return addAttribute(args...); // <-- Fehlermeldung
    }
    
    template < typename... Args>
    int addAttribute(const char* name, char* val, Args... args)
    {
    	//t ist abgetrenter Parameter 
    	// u ist 2.
    
    	const char *bla = typeid(val).name();
    
    	return addAttribute(args...);
    }
    
    template <typename... Args>
    int genXML(char* func,  Args... args)
    {
    	// func ist Funktionsname
    
    	return addAttribute( args... );
    }
    
    
    int main()
    {
    	genXML(__FUNCTION__, 
    		"att1", 5, 
    		"att2", "wort", 
    		"att3", 3, 
    		"Att4", "wort2" );
    
    
        return 0;
    }
    

    Die beiden "Endpunktfunktionen" sind nun kein Template mehr. Aber ich bekomme so wie der Code ist, folgende Fehlermeldung:

    
    Fehler	C2665	"addAttribute": Durch keine der 4 Überladungen konnten alle Argumenttypen konvertiert werden.	Zeile 41	
    

    Die Fehlermeldung habe ich mal im Code markiert.
    Weshalb findet er keine passende Überladung?



  • @KlammerKarl sagte in Anfänger benötigt Hilfe bei Templates:

    Beispiel:

    void SuperFunction1( char* param1, char* param2, int param3 )
    

    soll werden zu:

    <SuperFunction1 param1="abc" param2="def" param3="25" />
    

    Ich weiß jetzt nicht wirklich, wo das Problem ist.

    #include <cstddef>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    
    std::string my_to_string(char const *value) { return value; }
    
    template<typename T>
    std::string my_to_string(T value) { return std::to_string(value); }
    
    template<typename... Args>
    std::string genXML(char const *name, Args... args)
    {
    	std::ostringstream oss;
    	oss << '<' << name;
    
    	std::vector<std::string> foo{ my_to_string(args)... };
    
    	for (std::size_t i{}; i + 1 < foo.size(); i += 2) {
    		oss << " \"" << foo[i] << "\"=\"" << foo[i + 1] << '"';
    	}
    	oss << " />";
    	return oss.str();
    }
    
    int main()
    {
    	std::cout << genXML(__FUNCTION__, "att1", 5, "att2", "wort", "att3", 3, "Att4", "wort2", 1) << '\n';
    }


  • @Swordfish: Vielen Dank für dein Beispiel.

    @Swordfish sagte in Anfänger benötigt Hilfe bei Templates:

    Ich weiß jetzt nicht wirklich, wo das Problem ist.

    Mein Problem ist es zu verstehen, weshalb er mit die Fehlermeldung bringt.
    In deinem Besipiel wandelst du die int zu std::string um und schreibst das XML "manuell".
    Ich nutze eine Lib dafür und die erwartet für ganzzahlige Parameter eben auch den konkreten Typ.

    Ich werde mal schauen, ob ich den später brauche, falls nicht kann ich deinen Ansatz verfolgen.



  • @KlammerKarl sagte in Anfänger benötigt Hilfe bei Templates:

    Ich nutze eine Lib dafür und die erwartet für ganzzahlige Parameter eben auch den konkreten Typ.

    Wen du verraten würdest welche library und wie die entsprechenden Funktionen aufgerufen werden ...



  • @Swordfish sagte in Anfänger benötigt Hilfe bei Templates:

    @KlammerKarl sagte in Anfänger benötigt Hilfe bei Templates:

    Ich nutze eine Lib dafür und die erwartet für ganzzahlige Parameter eben auch den konkreten Typ.

    Wen du verraten würdest welche library und wie die entsprechenden Funktionen aufgerufen werden ...

    Ich nutze die ChilKat Library: https://www.chilkatsoft.com/refdoc/vcCkXmlRef.html

    Und hier dann:

    bool AddAttribute(const char *name, const char *value);
    
    bool AddAttributeInt(const char *name, int value); //für int
    

    Edit: Würde genre noch wissen, ob man den eigentlichen Aufruf noch eleganter machen kann? Also stat einzelner Parameter evetneull std::pair nutzen oder gibt es da noch etwas besseres?


Anmelden zum Antworten