无法在派生的子命名空间中实现方法 Class

Can't Implement Method in Subnamespace For Derived Class

具有嵌入式 C 经验的 Dotnet 开发人员进入 cpp 领域,让您了解我的 experience/knowledge。

我在 src/Core/Window/ 中有一个 class Window 基地:

namespace Pyrite::Core::Window
{
    class PYR_API Window
    {
    public:
        using EventCallbackFn = std::function<void(Pyrite::Event&)>;

        virtual ~Window();
        virtual void OnUpdate();

        virtual uint32_t GetWidth() const = 0;
        virtual uint32_t GetHeight() const = 0;

        virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
        virtual void SetVSync(bool isEnabled) = 0;
        virtual bool IsVSyncEnabled() const = 0;

        static Window* Create(const WindowProperties& props = WindowProperties());
    };
}

据此,我为特定于平台的 WindowsWindow 创建了一个派生的 class,我想将其存储在 src/Core/Window/Platform/:

namespace Pyrite::Core::Window::Platform
{
    class WindowsWindow : public Pyrite::Core::Window::Window
    {
    public:
        WindowsWindow(const WindowProperties& properties);
        virtual ~WindowsWindow();

        void OnUpdate() override;

        inline uint32_t GetWidth() const override { return m_Data.Width;    }
        inline uint32_t GetHeight() const override { return m_Data.Height; }

        inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
        void SetVSync(bool isEnabled) override { m_Data.VSyncEnabled = isEnabled; }
        bool IsVSyncEnabled() override {return m_Data.VSyncEnabled; }
    private:

        virtual void Init(const WindowProperties& properties);
        virtual void Close();

        GLFWwindow* m_Window;

        struct WindowData
        {
            std::string Title;
            uint32_t Width, Height;
            bool VSyncEnabled;

            EventCallbackFn EventCallback;
        };

        WindowData m_Data;

    };
}

但是,在 WindowsWindow.cpp 中,当我尝试为 Window::Create() 创建我的实现时,我收到一条关于无法在此处定义它的错误消息:

namespace Pyrite::Core::Window::Platform
{
    static bool s_GLFWInitialised = false;
        
    Window* Window::Create(const WindowProperties& properties)
    {
        return new WindowsWindow(properties);
    }
}
'Pyrite::Core::Window::Window *Pyrite::Core::Window::Window::Create(const Pyrite::Core::Window::WindowProperties &)': symbol cannot be defined within namespace 'Platform'  PyriteEngine    C:\repos\Pyrite\PyriteEngine\src\Core\Window\Platform\WIndowsWindow.cpp 9   

当我调整命名空间使它们都位于 Pyrite::Core::Window 中时,它似乎消失了......但是,我无法在子命名空间中定义它,这对我来说似乎很奇怪。我希望我的命名空间尽可能遵循我的文件夹结构(因为这几乎是我习惯的,它使事情保持逻辑和整洁)并且将平台特定的东西隐藏在子命名空间中对我来说似乎很有意义。

这只是我无法做到的事情还是我在这里遗漏了什么?

首先,C++ 中的源文件和命名空间之间的分离是一个特性,因为它们可以 在适当的情况下遵循相同的结构,但其他组织也是可能的。除此之外,不可能(按字面意思)做你要求的,因为它会产生奇怪的 “兄弟姐妹” 用于名称查找,被认为更麻烦比他们的价值。特别是,给定

namespace A {
  int i;
  struct X {void f(); void g(); void h();};
  namespace B {
    void g();
    namespace C {
      int i;
      void h();
      void X::f() {g(); h(); ++i;}  // pretend this is OK
    }
  }
}

尚不完全清楚 B::g and/or C::h 是否比 X::gX::h “更接近” X::f 的定义.也不清楚是否需要将 X::f 的定义移入或移出 class 发现的 i 变化。

您通常可以使用 using-declarations 来解决这些限制:上面的 X 可能在 B 中定义,但 A(或C!)中暴露。有时受影响的成员函数也可以移动到属于不同命名空间的 base class。