Compiler-Error über Meta-Template hier möglich?



  • Habe grade nen ziemlich dummen Bug gefixt.
    Der hat mich mehrere Stunden auf Trab gehalten.

    Folgender Code:

    typedef void* WindowHandle;
    

    Eigentlich soll man sowas nicht machen, ich weiss. Aber ich will hier HWND in den Headern vermeiden, damit es XPlatform bleibt. Will nicht wieder mit dem pImpl-Idion rummachen. Das ist immer doppelte Arbeit.

    Jetzt folgender Bug, vereinfacht dargestellt:

    Context* createPlatformContext(Window* win)
    {
    #ifdef WIN32
         return new Win32Context(win->GetHandle());
    #endif
    }
    

    Richtig gewesen wäre in diesem speziellen Fall:

    Context* createPlatformContext(WindowHandle win)
    {
    #ifdef WIN32
         return new Win32Context(win);
    #endif
    }
    

    Die 2te Überladung war noch nicht existent. Aber VC++ hat nicht gemeckert, weil er einfach Window* nach void* gecastet hat scheinbar.

    Meine Frage nun:
    Kann man den void* Pointer irgendwie spezialisieren damit es bei sowas in Zukunft einen Compilerfehler gibt? Irgendwas aus der Meta-Programmierung?
    Danke für eure Hilfe und erstmal gute nacht oder besser guten morgen :p.



  • typedef ist typedef. Ich würde keinen anderen Typ als genau den aus der <windows.h> nehmen, aus viel zu viel ANgst, daß es irgendwann knallt.

    Wie wäre es damit?

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    typedef void* WindowHandle;
    
    struct Window{
        WindowHandle h;
        WindowHandle GetHandle(){
            return h;
        }
    };
    
    struct Context{
    };
    
    struct Win32Context:Context{
        WindowHandle h;
        Win32Context(WindowHandle h){
            this->h=h;
        }
        template<typename T>
        Win32Context(T*)=delete;
    };
    
    Context* createPlatformContext(Window* win)
    {
         return new Win32Context(win->GetHandle());
    }
    
    int main(){
    }
    


  • Du hast recht, das war schlecht überlegt. Ich habe ja eine Basisklasse IPlatformWindow und eine Basisklasse IPlatformContext.
    Und im Prinzip braucht meine Library ja nur einen Pointer auf das alternative Fenster des Tools und darf new nicht selber aufrufen.
    Ich unterscheide jetzt einfach nicht mehr zwischen Tool und internem Fenster. Jedes Tool muss jetzt sein Fenster selber implementieren und kann der allgemeinen Funktion createWindow() alternativ einen Pointer mitgeben. Dieser wird dann auch nicht verwaltet.

    Mal wieder ein Fall von zu viel gedacht :D.
    Der void* typedef existiert zwar nicht, aber er ist nun weniger gefährlich da ich überall das IPlatformWindow übergeben kann und dann getWindowHandle() aufrufen kann. Darauf muss ich halt einfach achten.

    Ein weiterer Vorteil ist, dass jeder der ein Spiel mit meiner Lib macht, sein Fenster auch alternativ selber implementieren kann, anstatt meines zu nehmen.
    Das ist viel besser so^^ und ein extra feature ohne Aufwand 🤡.
    Danke nochmal.

    NLIPlatformWindow* NLSystemController::createWindow(const NLWindowSettings& settings, int minor, NLIPlatformWindow* window)
    {
        // Either use the pointer from the user or create the internal window.
        if ( window == NULL )
        {
            m_window = createPlatformWindow();
        }
        else
        {
            m_window = window;
        }
    
        // Setup the window.
        if ( m_window->wasCreated() == false )
        {
            if ( m_window->createWindow(settings) )
            {            
                try
                {
                    m_context = createPlatformContext(m_window, NLOpenGLSettings(3, minor, settings.bpp, settings.vsync));
                    m_context->initOpenGL(settings.width, settings.height);
                    m_context->setClearColor(NLCOLOR4F_BLUE);
                }
                catch(NLException& e)
                {
                    NLError(std::string("[NLSystemController] Failed to create Context: ") + e.what());
                    delete m_window;
                    delete m_context;
                    return NULL;
                }
    
                // Calculate ortho matrix 
                u32 w = static_cast<u32>(settings.getSize().x);
                u32 h = static_cast<u32>(settings.getSize().y);
                this->onResize(w, h);
    
                // Connect to resize Event
                m_window->connectSignalResize(NLBindResizeSlot(NLSystemController, onResize));
    
                // Load Standard Font Shader
                SystemController().getResourceManager().loadFontShader();
            }
            else
            {
                std::stringstream ss;
                ss << "[NLSystemController] Cannot create Window!";
                NLError(ss);
                delete m_window;
                throw NLException(ss.str(), true);
            }
        }
        else
        {
            NLWarning("[NLSystemController] NLSystemController::createWindow() called, but window already exists.");
            throw NLException("[NLSystemController] NLSystemController::createWindow() called, but window already exists.");
        }
        return m_window;
    }
    


  • Was spricht einfach dagegen?

    #ifdef _WIN32
    # include <Windows.h>
    #endif
    
    #ifdef _WIN32
      typedef HWND WindowHandle;
    #endif
    

Log in to reply