Frustrating issue

Hello,
I have built a small math parsing library, which compiles just fine, but when I integrate it into any programs I get these errors:
1
2
error: 'std::pair<_T1, _T2>::second' has incomplete type
error: forward declaration of 'struct Operator'


Operator is defined in Ub3rParse.h (Header internal to the library) and referenced in Ub3rMath.h (The external header for the library) as:
struct Operator;

The full source can be found here:
https://github.com/rscarson/UB3rMath

Thanks in advance, and sorry if this is in the wrong format (This is my first post here)
Richard Carson
Which file(s) and line(s) are these errors pointing to?
Ub3rMath.h line 49:
typedef unordered_map<string, Operator> OperatorList;

I know it is caused by Operator being defined in the library but only referenced as struct Operator (as a prototype) in the external header. I just don't know how to fix it without significantly complicating things.
You will need to actually define Operator or use pointers to Operator in your list and deal with the runtime allocation, etc. Not many other ways around it I can see.
The problem though, is because Ub3rMath.cpp has to reference Ub3rMath.h, redefining Operator gives an error.
You are only declaring Operator in Ub3rMath.h. You actually define it in Ub3rParse.h. In order for the typedef to make any sense Operator must be both declared and defined beforehand. Why not #include Ub3rParse.h in Ub3rMath.h and eliminate the forward declarations?
Last edited on
Because Ub3rParse.h is internal to the library... Ub3rMath.h is referenced from outside as well.
Ub3rParse.h does not exist outside.

Could I perhaps use preprocessor defines around the declarations in Ub3rMath.h to have the best of both worlds? Something like this perhaps...
1
2
3
#ifndef UB3RMATH_DEFINES
//Defines here
#endif 


and define UB3RMATH_DEFINES in Ub3rParse.h?

Maybe this will clear things up: (This is the code I am testing the library with)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <cmath>
#include "./../Ub3rMath/out/include/libUb3rMath.h"
using namespace std;

int main()
{
    Ub3rMath Engine;
    Engine.SetMode(MODE_DEGREES);
    string result = Engine.Solve("(5pi)(pi5)");
    if (Engine.LastError() == EQUATION_VALID)
    {
        cout << "Result of '" << Engine.LastEquation() << "' was '" << result << "'" << endl;
    }
    else
    {
        cout << "An error occured in equation '" << Engine.LastEquation() << "': " << Engine.LastErrorMessage() << " (error #" << Engine.LastError() << ")" << endl;
    }
    return 0;
}
Things like this still frustrate me as well. Would it be a horrible task to change the unordered_map to take a pointer to Operator and manage the allocation/tasks internally?
Again, why can you not include a definition of Operator in the Operator hearder? THis is normally how things are done; you cannot define functions in a class that has only been forward declared. You need a full definition for it to work.

If you cannot do this, that is a huge design flaw and you need to redesign your library.
Is this better?
(from Ub3rMath.h)
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef UB3RMATH_DEFINES
struct Variable;

/** Represents an operator */
struct Operator
{
    string name;
    string (*call)(double, double, string, int);
    int optype;
    int priority;
};
#endif
typedef unordered_map<string, Operator> OperatorList;


and Ub3rParse.h contains
#define UB3RMATH_DEFINES
Last edited on
Why are you doing stuff in Parse.h if the error you are getting is in Math.h?
the library has a header for internal use called Ub3rparse.h, there is also a wrapper class to provide a simple interface to programs using the library. The header for that class is Ub3rMath.h -- Which is thus also used by the external programs. But because both libraries are included in the library at compile time, the definition can not be in both or an error occurs. If I am doing this the wrong way, I apologize; I am still a student and this is the first library I try to build.
You need to have one header for both external and internal use - if you have to use a #define to tell whether it is being used internally or externally, that is also wrong.

The header should give the definitions of classes and their function prototypes only, the actuall implementation is your 'library'.
Some functions are not meant for outside use, though
That's why you put those functions in the private section of your classes, right? No problem in that case.

If whoever uses your library changes the header, that's their problem and you did the best you could to prevent it.
Topic archived. No new replies allowed.