template / typeid



  • Hallo ^^
    Ich habe eine Klasse geschrieben und wollte jz auch noch eine cast-fkt einbauen, die sollte so in etwa aussehen:

    Dazu hab ich aber mehrere Fragen:
    1. Versuch:

    //class xyz { public:
    template <typename T>
    	T Cast (void) const
    		{
    			std::stringstream stream;
    			stream << *this << std::ends; //ist das std::ends eigtl nötig oder sollte ich das lieber weglassen?
    			stream.seekg (std::ios_base::beg); //oder kann ich davon ausgehen, dass es immer an den Anfang "gespult" ist?
    			T R (0);
    			stream >> R;
    			return R;
    		}
    

    Jz gibt es nat. Probleme bei 'char *'
    Also mein zweiter Versuch:

    template <typename T>
    	T Cast (void) const
    		{
    			std::stringstream stream;
    			stream << *this << std::ends;
    			stream.seekg (std::ios_base::beg);
    			if (typeid (T) == typeid (char *))
    				{
    					std::string hlp = stream.str ();
    					char *R = new char[hlp.length ()+1];
    					strcpy_s (R, hlp.length (), hlp.c_str ());
    					return R;
    				}
    				else
    					{
    						T R (0);
    						stream >> R;
    						return R;
    					}
    		}
    

    Jz gibt es mit double (und wahrscheinlich auch jedem anderen Typ Probleme -.-
    Also habe ich das versucht:

    template <typename T>
    	T Cast (void) const
    		{
    			std::stringstream stream;
    			stream << *this << std::ends;
    			stream.seekg (std::ios_base::beg);
    			if (typeid (T) == typeid (double))
    				{
    					double R;
    					stream >> R;
    					return R;
    				}
    			else if (typeid (T) == typeid (char *))
    				{
    					std::string hlp = stream.str ();
    					char *R = new char[hlp.length ()+1];
    					strcpy_s (R, hlp.length (), hlp.c_str ());
    					return R;
    				}
    				else
    					{
    						T R (0);
    						stream >> R;
    						return R;
    					}
    		}
    

    Und es ist genau das passiert, was ich befürchtet hatte:
    Er bekommt den 'Cast' jz nur noch mit double hin - alle anderen ergeben Fehler, so fern sie nicht 'automatisch' aus double gecastet bzw gewandelt werden können -.-

    Wie stelle ich so was also am besten an?

    xyz /*class*/ a ();
    int b = a.Cast <int> ();
    

    finde ich auch nicht so schön... aber wenn ich es so anstellen wöllte:

    xyz /*class*/ a ();
    int b = a;
    

    müsste ich ja alles einzeln machen oder geht das auch iwie mit templates?

    Danke schon mal



  • warum sollte jemand deine objekte in char* konvertieren wollen?
    verbiete das, oder suche nach spezialisierung. typeid mit templates zu verwenden wird dir oft genug wahrscheinlich gar nicht kompilieren, denn stell dir mal vor, dein code wird für double instanziiert:

    //dann steht im else-teil erst wieder
    else
    {
       char* R (0);
       stream >> R;
       return R;
    }
    

    im übrigen:

    template <class T>
    T cast () const
    {
       T rv;
       stringstream str;
       str << *this;
       str >> rv;
       return rv;
    }
    

    das reicht.

    suchwort: spezialisierung.



  • Danke - daraus hab ich jz also das hier gemacht:

    //class xyz { public:
    template <typename T>
    	T Cast (void) const
    		{
    			T R; 
    			std::stringstream str;
    			str << *this;
    			str >> R;
    			return R;
    		};
    template < >
    	char* Cast <char *> (void) const
    		{
    			std::stringstream stream;
    			stream << *this;
    			std::string hlp = stream.str ();
    			const size_t l (hlp.length ()+1);
    			char *R = new char[l];
    			strcpy_s (R, l, hlp.c_str ());
    			return R;
    		};
    

    Und es scheint auch ganz wunderbar zu funktionieren : >



  • es ist gefährlich.

    warum sollte jemand, der Cast<int> aufruft, ein anderes verhalten bei Cast<char*> erwarten? (namentlich, den zeiger auch selbst löschen zu müssen)

    verbiete lieber Cast<char*>.


Anmelden zum Antworten