RTTI einzige Möglichkeit?



  • Hi,

    ich bin noch nicht so auf dem neusten Stand von Templates und so.

    Ich möchte mir einen "cast" schreiben im stil von lexical_cast (bekannt aus boost), jedoch der wchar_t zu char castet und zurück.

    Nun... das geht auch gut, jedoch benutze ich RTTI und das möchte ich sehr ungerne 😞

    Weiß einer wie folgender aufbau ohne RTTI aussieht?

    template<typename A, typename B> inline const A character_cast (const B& source, const std::locale& loc = std::locale())
    {
        // char zu wchar_t
        if (typeid(A) == typeid(std::basic_string<wchar_t>) && 
            typeid(B) == typeid(std::basic_string<char>))
        {
            blablabla (code weg gelassen)
        }
        // wchar_t zu char
        else if (typeid(A) == typeid(std::basic_string<char>) && 
                 typeid(B) == typeid(std::basic_string<wchar_t>))
        {
            blablabla (code weg gelassen)
        }
        // wchar_t zu wchar_t bzw. char zu char
        else if (typeid(A) == typeid(B))
        {
            return source;
        }
        else
            throw "bad character_cast";
    }
    

    Ich verzweifle daran 😞 bitte helft mir!



  • So spät noch auf der Arbeit? 😃 😃



  • Ein cast bedeutet ja, vereinfachend, eine "Uminterpretation" einer Variablen
    jedoch ohne eine inhaltliche Änderung. Und genau das funktioniert bei dir
    nicht weil, ein char-array inhaltlich ganz anders aussieht als ein wchar-array.
    Du musst also keinen cast sondern eine Konvertierung durchführen, inklusive
    Allokation von neuem Speicherplatz usw.



  • Redhat schrieb:

    Ein cast bedeutet ja, vereinfachend, eine "Uminterpretation" einer Variablen
    jedoch ohne eine inhaltliche Änderung. Und genau das funktioniert bei dir
    nicht weil, ein char-array inhaltlich ganz anders aussieht als ein wchar-array.
    Du musst also keinen cast sondern eine Konvertierung durchführen, inklusive
    Allokation von neuem Speicherplatz usw.

    was man trotzdem noch cast nennen kann. und darum gehts hier auch.

    @topic es gibt ne möglichkeit über template spezialisierung. such mal danach, dann wirste schnell was finden 🙂



  • otze schrieb:

    @topic es gibt ne möglichkeit über template spezialisierung. such mal danach, dann wirste schnell was finden 🙂

    auch wenn es hier überladung tut, da braucht man keine templates...



  • #include <string>
    #include <iostream>
    
    template<typename T, typename U> class character_cast_impl;
    
    //wstring -> wstring
    //string  -> string 
    template<typename T> 
    class character_cast_impl<T, T>
    {
    public:
    	const T operator()(const T &str1, const std::locale& loc)
    	{
    		return str1;
    	}
    };
    
    //wstring -> string
    template<> 
    class character_cast_impl<std::string, std::wstring>
    {
    public:
    	const std::string operator()(const std::wstring &str, const std::locale& loc)
    	{
    		//blablabla (code weg gelassen)
    		return "from wstring to string";
    	}
    };
    
    //string -> wstring
    template<> 
    class character_cast_impl<std::wstring, std::string>
    {
    public:
    	const std::wstring operator()(const  std::string &str, const std::locale& loc)
    	{
    		//blablabla (code weg gelassen)
    		return L"from string to wstring";
    	}
    };
    
    //helper method
    template<typename T, typename U> 
    inline T character_cast (
    	const U& source, 
    	const std::locale& loc = std::locale()) 
    {
    	character_cast_impl<T, U> impl;
    	return impl(source, loc);
    }
    
    int main()
    {
    	std::string str = "bla-bla-bla";
    	std::wstring wstr = L"bla-bla-bla";
    
    	std::cout << character_cast<std::string>(str) << std::endl;
    	std::wcout << character_cast<std::wstring>(str) << std::endl;
    	std::cout << character_cast<std::string>(wstr) << std::endl;
    	std::wcout << character_cast<std::wstring>(wstr) << std::endl;
    }
    


  • Hi,

    danke ssm, aber der code lässt sich nicht compilieren:

    Compiling...
    main.cpp
    main.cpp(87) : error C2065: 'T' : undeclared identifier
    main.cpp(87) : error C2687: cannot define a nested UDT of a template class out of line
    main.cpp(87) : fatal error C1903: unable to recover from previous error(s); stopping compilation
    

    Hier gibts den Fehler:

    //wstring -> wstring 
    //string  -> string 
    template<typename T> 
    class character_cast_impl<T, T>    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    { 
    public: 
        const T operator()(const T &str1, const std::locale& loc) 
        { 
            return str1; 
        } 
    };
    


  • Template Neuling schrieb:

    Hi,

    danke ssm, aber der code lässt sich nicht compilieren:

    was für einen Compiler hast du?



  • VC++7.0



  • Template Neuling schrieb:

    VC++7.0

    VC7.0 ist leider keinen normalen Compiler, da er keine partial specialization for templates kann.
    um so was kompilieren zu können brauchst du VC7.1



  • hm.... schade....

    gibts denn sonst keine möglichkeit?.... 😞



  • Template Neuling schrieb:

    gibts denn sonst keine möglichkeit?.... 😞

    ja, meinen beitrag lese und die templates sein lassen



  • Wenn du die Cast-Synthax nachahmen willst, kannst du das ja tun. Die dahinter steckende Implementation kann trotzdem mit gewöhnlicher Überladung arbeiten (siehe Shade of Mines Antwort).



  • Helium schrieb:

    Wenn du die Cast-Synthax nachahmen willst, kannst du das ja tun. Die dahinter steckende Implementation kann trotzdem mit gewöhnlicher Überladung arbeiten (siehe Shade of Mines Antwort).

    wer hat dich das wort synthax gelehrt?



  • 🙄

    Gute Frage. Scheinbar niemand. Ich meinte eigentlich Schreibweise nicht Synthax, entschuldige.



  • #include <string> 
    #include <iostream> 
    
    namespace util
    {
    	template<typename T>
    	struct TypeToType
    	{
    	};
    }
    
    namespace impl
    {
    	using namespace util;
    
    	//==================================================
    	//stuff for stupped VC++7.0 and VC++6.0
    
    	std::string character_cast_impl(
    		const std::string &str, 
    		const std::locale& loc, 
    		TypeToType<std::string>)
    	{
    		return str;
    	}
    
    	std::wstring character_cast_impl(
    		const std::wstring &str, 
    		const std::locale& loc, 
    		TypeToType<std::wstring>)
    	{
    		return str;
    	}
    	//==================================================
    
    	std::string character_cast_impl(
    		const std::wstring &str,
    		const std::locale& loc,  
    		TypeToType<std::string>)
    	{
    		return "wstring->string";
    	}
    
    	std::wstring character_cast_impl(
    		const std::string &str, 
    		const std::locale& loc,
    		TypeToType<std::wstring>)
    	{
    		return L"string->wstring";
    	}
    }
    
    //helper method 
    template<typename T, typename U> 
    inline T character_cast ( 
        const U& source, 
        const std::locale& loc = std::locale()) 
    { 
        return impl::character_cast_impl(
    		source, 
    		loc, 
    		util::TypeToType<T>());    
    } 
    
    int main() 
    { 
        std::string str = "bla-bla-bla"; 
        std::wstring wstr = L"bla-bla-bla"; 
    
        std::cout << character_cast<std::string>(str) << std::endl; 
        std::wcout << character_cast<std::wstring>(str) << std::endl; 
        std::cout << character_cast<std::string>(wstr) << std::endl; 
        std::wcout << character_cast<std::wstring>(wstr) << std::endl; 
    
    	return true;
    }
    


  • @ssm: hast du den code geschrieben?



  • euch ist aber schon klar, dass eine einfache überladung zwar den 'leetness faktor' von einem eigenen casting operator nicht hat, aber dieser 'cast operator' ist effektiv nutzlos, weil er nur 2 konvertierungen kann.



  • Helium schrieb:

    Gute Frage. Scheinbar niemand. Ich meinte eigentlich Schreibweise nicht Synthax, entschuldige.

    Ich glaube es ging eher um die Schreibweise von Syntax 😉 .



  • Volkard macht genauso viele Rechtschreibfehler wie ich hier im Forum. Beinahe jeder hätte darüber meckern dürfen, aber nicht er.


Anmelden zum Antworten