Brainfarts with #include/typedef problem

I've probably just been coding way too much at once, but I can't seem to figure out the best solution to this.

I have a file, Paint_View_GUI.hpp.
In it, I define a PaintView_SFML class, and at the bottom of the .hpp file, I have typedef PaintView_SFML PaintView;

This file is included in multiple places.

In another file, MenuFunctions.hpp, I have the following lines:
1
2
3
4
5
6
7
8
...
#include <Paint_Mode.hpp>
#include <Paint_View_GUI.hpp>

typedef void (*PulldownFunction)(PaintModel&, PaintView&);
#define menu_functions_inline inline

...


The error message I get is "Error PaintView has not been declared", line 5 of the above snippet. This error is propagated to every instance of PaintView in the MenuFunctions.hpp file.

I realize this probably isn't a lot to go off of, but any troubleshooting tips possible? Thank you.

EDIT: It appears it's a circular dependency I have, I'll keep messing around with stuff.
Last edited on
Make sure that you don't have any circular dependencies and that you are using unique include guards in all of your header files.
Last edited on
I think I almost solved it, there's this annoying issue which I guess is a design in the language itself, if I forward declare a class as "class PaintView", it says it conflicts with the declaration "typedef class PaintView_SFML PaintView". Why are the typedefs making this hell =(
But in trying to fix that I have incomplete type errors.
I'll keep trying.
Last edited on
I solved my issue for now.

Here's an example to illustrate the problem:
I have a class declared as class MyClass_Specific {};
Then I have a typedef MyClass_Specific MyClass.

The goal of this was so that I could interchange classes that have compatible interfaces (MyClass_ThisWay, MyClass_ThatWay both having the same functionality, but one would be meant for the console while another one would be meant for a GUI, and I could interchange it at compile time)

There is then this problem with forward declaring class MyClass, or something along those lines.
In main, it would argue that I had an incomplete type if I specified MyClass object;, but wouldn't give me an error until later if I did MyClass_Specific object;. The error it would still eventually give is that a function expects a MyClass but is given a MyClass_Specific.

tl;dr I got rid of the typedef and just made the definition itself be MyClass, and everything seems peachy now. If I need to change things around later, I'll write a script or something to manually re-name instances.

Frustrating though, don't understand what exactly the limitations of typedefing and forward declarations are.
Last edited on
Frustrating though, don't understand what exactly the limitations of typedefing and forward declarations are.

You have something else going on in your code that you are not elucidating.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 // http://ideone.com/L5mnD2
class MyClass_Specific {};

typedef MyClass_Specific MyClass;

void func(MyClass obj) {}

int main()
{
    MyClass object;
    MyClass_Specific object2;

    func(object);
    func(object2);
}

You're right, here's my attempt at a minimal example.

What would be a clean way to fix this?
The error is that the typedef conflicts with the forward declaration of class View.
The goal here is to only have to change the code in one place if I want to switch to a different View implementation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include <vector>

class Model;
class View;

struct Menu {
    std::vector<void(*)(Model&, View&)> functions;
};

struct Model {
    int stuff;
};

struct View_Specific {
    Menu menu;
};
typedef View_Specific View;

void foo(Model& model, View& view)
{
    model.stuff++;
}

int main()
{
    Model model;
    View view;
    view.menu.functions.push_back(foo);
    view.menu.functions[0](model, view);
}
Considered parameterizing Menu?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <vector>
    
template <typename V>
struct Menu {
    using ViewType = V;    // equivalent to typedef V ViewType;
    std::vector<void(*)(struct Model&, ViewType&)> functions;
};

struct Model {
    int stuff;
};

struct View_Specific {
    Menu<View_Specific> menu;
};

typedef View_Specific View;

void foo(Model& model, View& view)
{
    model.stuff++;
}

int main()
{
    Model model;
    View view;
    view.menu.functions.push_back(foo);
    view.menu.functions[0](model, view);
}
Yeah that looks like it'll work, similar to that compile-time polymorphism technique I forget the acronym of. Thanks for your time.
Topic archived. No new replies allowed.