forward declaring typedefs

Hi everyone,

I'm using some rather large external libraries, and I want to load them in my .cpp file only. so, my header looks like this:

1
2
3
4
5
6
7
8
9
10
11

namespace {
// hidden declarations
namespace geometry {
class Point;
class Polygon;
class Box;
//etc
}
}


In the declaration of the main class in that header, I merely use these as pointers or references.

The .cpp file looks as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Boost
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>

namespace {
namespace geometry {
typedef boost::geometry::model::d2::point_xy<double> Point;
typedef boost::geometry::model::polygon<Point, false> Polygon;
typedef boost::geometry::model::box<Point> Box;
}
}


This doesn't work however:


error C2371: '`anonymous-namespace'::geometry::Point' : redefinition; different basic types
1>          e:\..\..\..\..\..\NavigationMesh.h(10) : see declaration of '`anonymous-namespace'::geometry::Point'


What can I do to forward declare external classes like this?

Thanks!
If you want to achieve your objective your member variables in your class of the types coming from the Boost library will need to be forward declared, and they will need to be pointers. In the header the member pointers don't require 'knowldege' of the Boost classes, your code will know this in the source file where you provide the Boost headers, etc...

header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Point;
class Polygon;
class Box;

class YourClass
{
   public:
   ...

private:
   Point* m_pMyPoint;
   Polygon* m_pMyPolygon;
   Box* m_pMyBox;
};


HTH
Last edited on
What can I do to forward declare external classes like this?
You can't. typedef is not class

Why is it a problem to include the typedefs?
These boost libraries are quite large and contain a load of templates, making code hinting quite slow if I put them in headers that are included in (many) other files. So, I encapsulated all the boost stuff into the .cpp file, but some of the private data members are still of those boost types.
ajh32, I'm not sure what's different in your proposition compared to my own code? I tried removing namespaces but it gives the same error.
How would I tell my .cpp file that the forward declared classes are actually the boost classes?

Thanks!
Ok, I fixed it by making 'full' forward declarations of the boost classes. It's a bit bulky, but I guess it makes sense that the compiler needs to know this information.


However, one question remains:

How can I prevent these forward declarations from polluting my main namespace? If I import this header, I will automatically gain access to these classes :(
try follow methord , just put below codes in your .h and include boost's header file in your .cpp
1
2
3
4
5
6
7
8
9
10
11
class boost::geometry::model::d2::point_xy<double>;
class boost::geometry::model::polygon<Point, false>;
class boost::geometry::model::box<Point>;

namespace {
namespace geometry {
typedef boost::geometry::model::d2::point_xy<double> Point;
typedef boost::geometry::model::polygon<Point, false> Polygon;
typedef boost::geometry::model::box<Point> Box;
}
} 
by making 'full' forward declarations of the boost classes
What does that mean?

What is your main namespace? Why would it be polluted by boost?

Honestly: I don't really see what's the problem is that you're trying to solve.

By the way: what's the use of the unnamed namespace?
Hey coder777,

By full forward declaration, I mean I have to write it all out like this:

1
2
3
4
5
6
7
namespace boost {
namespace geometry {
namespace model {
class Polygon;
}
}
}


However, when I declare this in myheader.h, any class including myheader.h will have that in its scope. I don't want this, because myheader.h will be the only file using these boost headers, so there's no sense in other classes knowing about it. It's just pollution.

what's the use of the unnamed namespace?


unnamed namespace (anonymous namespace) is used just for that: Everything in it will be unavailable for other files. So, you can avoid polluting the namespace.
However, when I declare this in myheader.h, any class including myheader.h will have that in its scope. I don't want this, because myheader.h will be the only file using these boost headers, so there's no sense in other classes knowing about it. It's just pollution.

If you include a header file in another translation unit, then everything in that header becomes part of that translation unit. It's nonsense to say "myheader.h will be the only file using these boost headers", because every file that includes myheader.h will contain those bits of myheader.h that use the Boost headers. So every file that includes myheader.h will, effectively, need to use the Boost headers.

Is the problem that you have stuff in myheader.h that actually doesn't actually need to be included in other files? If so, you should look at refactoring it to only contain what it needs to. As a general principle, you should keep header files as minimal as possible, so that they contain only what they need to contain so serve whatever purpose they're for. That's how you avoid unnecessary coupling in your code.

Without seeing your header file, it's difficult to give any more specific advice.
Last edited on
I think you have some misconception what namespaces are.

unnamed namespace (anonymous namespace) is used just for that: Everything in it will be unavailable for other files.
No. unnamed namespaces have no other effect than this weird 'internal linkage' for global variables thing. Everything can be accessed whatsoever is in your header file. Just try it...

I don't want this, because myheader.h will be the only file using these boost headers, so there's no sense in other classes knowing about it. It's just pollution.
If noone uses your 'Point' why is a forward declaration necessary? You should be able to leave everything in your cpp.
When it is actuall necessary to know about the type of 'Point' then it absolutely ok to include everything that is necessary for this type.

And since boost is a completely separated namespace your namespace isn't 'polluted' at all.
Honestly I have problems to understand what pollution in this context means.
Thanks for the response, I've been looking around, I see some conflicting information on anonymous namespaces, but it seems you are right. I can access them from other files too. My class uses these boost objects privately only: It keeps track of a few vectors of Points, Polygons, etc.

To be honest, I don't see a very clean way to keep those boost classes in the .cpp only, unless I save all the data as raw data. Maybe that's the way to go? What would you do?
It is, IMHO, a flaw of C++ that you have to put some private implementation details in the header file. It would be much more elegant if you could define the private part of a class inside the .cpp file instead. But we're stuck with what we've got. If you're using boost types for private data, you then you'll need to put whatever definitions they need - be that forward declaration or header file inclusion - into the header too.

Are you aware of the "pImpl" idiom? If this is really an issue, you can hide the implementation details inside a separate class containing the implementation, and have a pointer to the implementation class as a data member in the principal class (requiring only forward declaration of the implementation class). Hence "pImpl" - pointer to implementation.

I've rarely used it myself, but this is exactly the kind of situation it's designed for.
That sounds nice, but I think I'll settle with what I've got. I'm just trying to be as neat as possible, and with forward declarations of the boost classes it's the cast that they are visible, but at least unusable for other classes (because they are just declarations). So it's fine! Cheers!
Topic archived. No new replies allowed.