0

Following problem: I am currently adding namespaces into my project and there's one thing that i can't seem to get around, friending methods in nested namespaces. If class x is in the namespace a and namespace b but class y that wants to friend the method in class x is in namespace a and namespace b it can't work since class y doesn't have a clue about namespace b, but you can't include the header of class x because class x already includes class y. Is there a way to fix this ?

Errors i get:

'Kinnon::Time::Time::m_DeltaTime': cannot access private member declared in class 'Kinnon::Time::Time' 'Main': is not a class or namespace name 'Main': is not a class or namespace name

Time.h

#pragma once
namespace Kinnon { namespace Time {

class Time
{
    friend void Main::MainComponent::run();
public:
static const float &getDeltaTime();
private:
    Time();
    static float m_DeltaTime;
};
} }

MainComponent.h

#pragma once
#include <chrono>
#include "..\graphics\Window.h"
#include "..\input\Input.h"
#include "..\time\Time.h"

namespace Kinnon { namespace Main { 

typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::duration<float> fsec;

class MainComponent
{
public:
    MainComponent(const char *title, unsigned int width, unsigned int height);
    ~MainComponent();
    void run();
    void tick();
    void render();
private :
    Graphics::Window m_Window;

};
} }

MainComponent.run() method:

namespace Kinnon { namespace Main {
void MainComponent::run()
    {
        auto lastTime = Clock::now();
        auto currentTime = Clock::now();
        while(!m_Window.shouldClose())
        {
            lastTime = Clock::now();
            tick();
            render();
            currentTime = Clock::now();
            fsec passedTime = currentTime - lastTime;
            Time::Time::m_DeltaTime = passedTime.count();
        }
    }
    }}

1 Answers1

0

You can do as follows:

  1. Use Include guards within MainComponent.h, and take out the #include "Time.h" from it.
  2. Put your MainComponent.run() function in a .cpp file, and include both Time.h and MainComponent.h in it.
  3. include MainComponent.h in Time.h.

So you'll end up with something like this:
in MainComponent.h:

#ifndef __MAIN_COMPONENT_H__
#define __MAIN_COMPONENT_H__
#pragma once
#include <chrono>
#include "..\graphics\Window.h"
#include "..\input\Input.h"

namespace Kinnon { namespace Main { 

typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::duration<float> fsec;

class MainComponent
{
public:
    MainComponent(const char *title, unsigned int width, unsigned int height);
    ~MainComponent();
    void run();
    void tick();
    void render();
private :
    Graphics::Window m_Window;

};
} }
#endif

in Time.h:

#include "MainComponent.h"
#pragma once
namespace Kinnon { namespace Time {

class Time
{
    friend void Main::MainComponent::run();
public:
static const float &getDeltaTime();
private:
    Time();
    static float m_DeltaTime;
};
} }

and in MainComponent.cpp:

#include "MainComponent.h"
#include "Time.h"
namespace Kinnon { namespace Main {
void MainComponent::run()
    {
        auto lastTime = Clock::now();
        auto currentTime = Clock::now();
        while(!m_Window.shouldClose())
        {
            lastTime = Clock::now();
            tick();
            render();
            currentTime = Clock::now();
            fsec passedTime = currentTime - lastTime;
            Time::Time::m_DeltaTime = passedTime.count();
        }
    }
    }}

If you'd like another solution, you can read about it here (using forward declaration, with each class keeping a pointer to an instance of the other class).

Community
  • 1
  • 1
OfirD
  • 9,442
  • 5
  • 47
  • 90