Bounty question: So, these two Foos aren't the same thing. Fine. The second form is given in a library. How do I forward-declare it given that I can't change it?
I always thought C and C++ allowed repeated declarations provided that there were no repeated definitions. Then I came across this problem when trying to write C++ code which extends a C library.
struct Foo;
typedef struct {} Foo;
This gives the following error:
'struct Foo' has a previous declaration as 'struct Foo'
I want to forward-declare, darn it! What's wrong here?
typedef-ing anonymous struct is a practice that pre-dates C++03 and is mainly oriented to retain compatibility with pre-C99 compilers.
Given that this is 2011, and that both C++ and C are changed, I wonder why there is no more up-to-date version of such a library!
If it is not in development anymore, you cannot "leave", but just "survive" and change it is the way to do that.
If still in deployment, submit the issue to the development team.
If you need a workaround, consider that struct can inherit.
So, write a forward declaration like
struct MyFoo;
and define it as
#include "old_library.h"
struct MyFoo: public Foo {};
And in all your code, forget about Foo and always use MyFoo.
You're declaring two different entities with the same name. The first, struct Foo, is a struct named Foo. The second is an alias for an anonymous struct.
If you do instead:
struct Foo;
struct Foo {};
It works, because you're declaring a struct named Foo in both situations.
You cannot forward declare anonymous structs. You're left with two choices: include the whole definition, or change the header and name the struct.
In a similar situation, I have a legacy C header with something like
== old_library.h ==
typedef struct { int data; } Foo;
== /old_library.h ==
I use it in a C++ class of my own, as parameter for a private method:
class C {
void run(Foo *ds);
...
}
To avoid #include "old_library.h" from C.hpp, I use the following forward declaration:
class C {
struct Foo;
void run(Foo *ds);
...
}
and in C.cpp I have the following statements:
extern "C" {
#include "old_library.h"
}
struct C::Foo : public ::Foo {};
This way, I use C::Foo instead of Foo transparently, and don't need a MyFoo!
You don't need to typedef structs in C++:
struct Foo; // Forward declaration
struct Foo
{
}; // Definition
If you want to call it just Foo instead of struct Foo in C, you do need the typedef, which can also be done in different ways:
struct Foo; /* Forward declaration */
struct Foo /* The name is needed here */
{
}; /* Definition */
typedef struct Foo Foo; /* typedef */
or
struct Foo; /* Forward declaration */
typedef struct Foo /* The name is needed here */
{
} Foo; /* Definition and typedef combined */
You can of course use the form struct Foo in both C and C++.
Your forward declaration declares that there will be a struct called Foo.
Your second declaration is of a typedef called Foo. These are not the same thing.
For a forward declaration of a typedef, you need to refer to the thing that is being typedeffed, so like:
struct foo;
typedef foo bar;
class foo{};
Since you want to forward declare an anonymous struct, you can neither give it a name in the forward declaration of the original entity, nor can you refer to it when typedefing it. The "logical" syntax would be:
struct ;
typedef bar;
class {};
But since this is obviously not possible, you can not forward declare anonymous structs.
To go standardese, lets have a look at 9.1-2:
A declaration consisting solely of class-key identifier; is either a
redeclaration of the name in the current scope or a forward
declaration of the identifier as a class name. It introduces the class
name into the current scope.
No identifier, no forward declaration.
Bottom line of this: avoid anonymous structs unless they give you an advantage that you really need.
Your specific compiler may make a difference here.
Using MinGW GCC 3.4.5, both declarations compile with no errors or warnings (using -Wall)
struct Foo;
typedef struct {} Foo;
and
struct Foo;
typedef struct Foo {} Foo;
Is it possible a forward-declaration already exists inside the library? For instance, to allow a circular pointer:
struct Foo;
typedef struct Foo {
struct Foo *fooPtr;
} Foo;
If this already exists within the library headers, it would cause the error you describe.
IMHO, simply change your typedef to,
typedef struct Foo {} Foo;
^^^^^
There is no harm and it will still compatible in both C & C++. Now you can forward declare it.
[Note: If you still insist on on not touching the typedef at all then here is the dirty trick.
struct Foo;
#define struct struct Foo
#include"Foo.h" // contains typedef struct {} Foo;
#undef struct
This will work, only if Foo.h contains only 1 struct declaration. I don't recommend it.]
I think I recently ran into the same problem as the original poster, and have resolved it as below:
I am writing a wrapper around a third-party provided API defined as:
Foo.h:
typedef struct _foo
{
int i;
} Foo;
Foo* MakeFoo();
int UseFoo(Foo* foo);
My wrapper needs to have Foo as a member, but I don't want to expose Foo to all consumers of my wrapper.
UberFoo.h:
#pragma once
struct _foo; // forward declare the actual type _foo, not the typedef Foo
class UberFoo
{
public:
UberFoo();
int GetAnswer();
private:
_foo* f;
};
UberFoo.cpp:
#include "UberFoo.h"
#include "Foo.h"
UberFoo::UberFoo()
{
this->f = MakeFoo();
}
int UberFoo::GetAnswer()
{
return UseFoo(f);
}
Now, the consumers of my class can instantiate it without having access to the actual definition of _foo/Foo. This would also work if I needed to pass pointers to _foo as parameters or return them from functions as well as having a member _foo.
main.cpp:
#include <cstdio>
#include "UberFoo.h"
int main(int argc, char* argv[])
{
UberFoo u;
printf( "The Answer = %d\n", u.GetAnswer());
return 0;
}
The trick here was to forward declare the actual struct type, not the typedef'd name. Note that it is critical that the struct not be anonymous, as is common in older C code:
typedef struct // the actual struct type underlying the typedef is anonymous here
{
int i;
} ThisWontWork;
Hope this helps!
You can't forward declare it, since its unnamed. Its an unnamed struct, for which Foo is a typedef.
Why don't you just avoid forward decl.
If the second definition was in a header file, you could include the header file first in your C++ header file. To make C++ think it as C header, embracing #include with extern "C" { and } must be suffice in most case.
You are trying to typedef a previously used name. The statement is perfectly valid, only you need to use a different name.
struct Foo; // Forward declaration of struct Foo
typedef struct {} anotherFoo; // Another structure typedefed
struct Foo {
// Variables
}; // Definition of the forward declared Foo.
Note that the typedef cannot be used in the same name.
Related
Why won't the compiler let me forward declare a typedef?
Assuming it's impossible, what's the best practice for keeping my inclusion tree small?
You can do forward typedef. But to do
typedef A B;
you must first forward declare A:
class A;
typedef A B;
For those of you like me, who are looking to forward declare a C-style struct that was defined using typedef, in some c++ code, I have found a solution that goes as follows...
// a.h
typedef struct _bah {
int a;
int b;
} bah;
// b.h
struct _bah;
typedef _bah bah;
class foo {
foo(bah * b);
foo(bah b);
bah * mBah;
};
// b.cpp
#include "b.h"
#include "a.h"
foo::foo(bah * b) {
mBah = b;
}
foo::foo(bah b) {
mBah = &b;
}
To "fwd declare a typedef" you need to fwd declare a class or a struct and then you can typedef declared type. Multiple identical typedefs are acceptable by compiler.
long form:
class MyClass;
typedef MyClass myclass_t;
short form:
typedef class MyClass myclass_t;
In C++ (but not plain C), it's perfectly legal to typedef a type twice, so long as both definitions are completely identical:
// foo.h
struct A{};
typedef A *PA;
// bar.h
struct A; // forward declare A
typedef A *PA;
void func(PA x);
// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
Because to declare a type, its size needs to be known. You can forward declare a pointer to the type, or typedef a pointer to the type.
If you really want to, you can use the pimpl idiom to keep the includes down. But if you want to use a type, rather than a pointer, the compiler has to know its size.
Edit: j_random_hacker adds an important qualification to this answer, basically that the size needs to be know to use the type, but a forward declaration can be made if we only need to know the type exists, in order to create pointers or references to the type. Since the OP didn't show code, but complained it wouldn't compile, I assumed (probably correctly) that the OP was trying to use the type, not just refer to it.
Using forward declarations instead of a full #includes is possible only when you are not intending on using the type itself (in this file's scope) but a pointer or reference to it.
To use the type itself, the compiler must know its size - hence its full declaration must be seen - hence a full #include is needed.
However, the size of a pointer or reference is known to the compiler, regardless of the size of the pointee, so a forward declaration is sufficient - it declares a type identifier name.
Interestingly, when using pointer or reference to class or struct types, the compiler can handle incomplete types saving you the need to forward declare the pointee types as well:
// header.h
// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;
typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;
// Using the name without the class/struct specifier requires fwd. decl. the type itself.
class C; // fwd. decl. type
typedef C* CPtr; // no class/struct specifier
typedef C& CRef; // no class/struct specifier
struct D; // fwd. decl. type
typedef D* DPtr; // no class/struct specifier
typedef D& DRef; // no class/struct specifier
I had the same issue, didn't want to mess with multiple typedefs in different files, so I resolved it with inheritance:
was:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
did:
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
Worked like a charm. Of course, I had to change any references from
BurstBoss::ParticleSystem
to simply
ParticleSystem
I replaced the typedef (using to be specific) with inheritance and constructor inheritance (?).
Original
using CallStack = std::array<StackFrame, MAX_CALLSTACK_DEPTH>;
Replaced
struct CallStack // Not a typedef to allow forward declaration.
: public std::array<StackFrame, MAX_CALLSTACK_DEPTH>
{
typedef std::array<StackFrame, MAX_CALLSTACK_DEPTH> Base;
using Base::Base;
};
This way I was able to forward declare CallStack with:
class CallStack;
As Bill Kotsias noted, the only reasonable way to keep the typedef details of your point private, and forward declare them is with inheritance. You can do it a bit nicer with C++11 though. Consider this:
// LibraryPublicHeader.h
class Implementation;
class Library
{
...
private:
Implementation* impl;
};
// LibraryPrivateImplementation.cpp
// This annoyingly does not work:
//
// typedef std::shared_ptr<Foo> Implementation;
// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
// C++11 allows us to easily copy all the constructors.
using shared_ptr::shared_ptr;
};
Like #BillKotsias, I used inheritance, and it worked for me.
I changed this mess (which required all the boost headers in my declaration *.h)
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
typedef boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;
into this declaration (*.h)
class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;
and the implementation (*.cpp) was
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
class VanillaAccumulator : public
boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>>
{
};
Another solution is to put the forward declarations and typedefs into a separate header and include that:
// ForwardDeclarations.h
#pragma once
namespace Foo
{
struct Bar;
typedef Bar Baz;
}
// SomeFile.h
#include "ForwardDeclarations.h"
Foo::Baz baz;
Of course this doesn't actually reduce the number of files to include and the compiler still has to read this file from the disk, but at least the contents are simpler than the full definition. You could add more forward declarations to the same file and include it in relevant places.
When and why should we use the 'struct' keyword when declaring a class pointer variable in C++?
I've seen this in embedded environments so I suspect that this is some kind of hold over from C. I've seen plenty of explanations on when to use the 'struct' keyword when declaring a struct object as it relates to namespaces in C (here), but I wasn't able to find anyone talking about why one might use it when declaring a class pointer variable.
Example, in CFoo.h:
class CFoo
{
public:
int doStuff();
};
inline Foo::doStuff()
{
return 7;
}
And later in a different class:
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
There's rarely a reason to do this: it's a fallover from C and in this case the programmer is simply being sentimental - perhaps it's there as a quest for readability. That said, it can be used in place of forward declarations.
In some instances you might need to disambiguate, but that's not the case here. One example where disambiguation would be necessary is
class foo{};
int main()
{
int foo;
class foo* pf1;
struct foo* pf2;
}
Note that you can use class and struct interchangeably. You can use typename too which can be important when working with templates. The following is valid C++:
class foo{};
int main()
{
class foo* pf1;
struct foo* pf2;
typename foo* pf3;
}
There are two reasons to do this.
The first one is if we are going to introduce a new type in the scope using an elaborated name. That is in this definition
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
the new type struct CFoo is introduced in the scope provided that it is not yet declared. The pointer may point to an incomplete type because pointers themselves are complete types.
The second one is when a name of a class is hidden by a declaration of a function or a variable. In this case we again need to use an elaborated type name.
Here are some examples
#include <iostream>
void CFoo( const class CFoo * c ) { std::cout << ( const void * )c << '\n'; }
class CFoo
{
public:
int doStuff();
};
int main()
{
class CFoo c1;
return 0;
}
Or
#include <iostream>
class CFoo
{
public:
int doStuff();
};
void CFoo( void ) { std::cout << "I am hidding the class CGoo!\n"; }
int main()
{
class CFoo c1;
return 0;
}
In C, two different styles are the most common:
typedef struct { ... } s; with variables declared as s name;.
struct s { ... }; with variables declared as struct s name;
In C++ you don't need to typedef to omit the struct keyword, so the former style is far more in line with the C++ type system and classes, making it the most common style in C++.
But then there are not many cases in C++ when you actually want to use struct instead of class in the first place - structs are essentially classes with all members public by default.
The reason for this may be as simple as not having to include a header file whose contents aren't needed other than for announcing that CFoo names a type. That's often done with a forward declaration:
class CFoo;
void f(CFoo*);
but it can also be done on the fly:
void f(struct CFoo*);
I have the following situation:
typedef void (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
This happens because an instance of ClassName needs to pass a pointer itself to the client. However, If I write things in this order, I get complains about ClassName not declared, whatnot. However, if I switch them around, I get complains about F_POINTER not being declared when I declare the instance in the class.
So maybe I'm missing something simple here, but how would I accomplish this?
Forward declaration:
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
Or shorter:
typedef (*F_POINTER)(class ClassName*); // implicit declaration;
This seems to be working under GCC 4.5.2 (mingw32):
typedef void (*F_POINTER)(class ClassName);
class ClassName {};
void f (ClassName) {}
int main ()
{
F_POINTER x = f;
}
I wouldn't trust my life on whether it is legal C++ or not, not even the pointer version described by other people. Forward declarations and pointers do not solve everything, for example it is not possible to declare methods that throw pointers of incomplete types, you need full definition for that. This might be similarly illegal, just accepted by compilers.
Forward declare ClassName. The type can be incomplete to use a pointer to it.
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName { ... };
Alternatively, move the typedef inside the class. Also consider using boost::function/std::function instead of function pointers.
Either you can forward declare it as,
class ClassName;
typedef void (*F_POINTER)(ClassName*); // assume that return is `void`
before the F_POINTER or you can use the template trick to avoid such hassels for every class:
template<typename RETURN, typename ARGUMENT>
struct FuncPtr { typedef RETURN (*F_POINTER)(ARGUMENT); };
Usage:
class ClassName {
public:
FuncPtr<void,ClassName*>::F_POINTER f;
};
Going by gcc version 4.4.2, it appears that saying
typedef struct foo foo;
// more code here - like function declarations taking/returning foo*
// then, in its own source file:
typedef struct foo
{
int bar;
} foo;
is legal in C++ but not in C.
Of course I have a body of code that compiles fine in C++ by using the foo type but it appears I must make it use struct foo (in the header file) to get it to work with some C code another developer wrote.
Is there a way to predeclare a struct typedef foo foo in gcc C without getting a "redefinition of typedef 'foo'" error when compiling for C? (I don't want the marginally illegal and less clean underscore solution of struct typedef _foo foo)
Is this what you need?
// header (.h)
struct foo;
typedef struct foo foo;
foo *foo_create();
// etc.
// source (.c)
struct foo {
// ...
}
I also tend to prefix my struct name with an underscore when typdefing to make its privateness clear and prevent possible name clashes.
One of the differences between C++ and C is that in C++ it is legal to make a repetitive typedef in the same scope as long as all these typedef are equivalent. In C repetitive typedef is illegal.
typedef int TInt;
typedef int TInt; /* OK in C++. Error in C */
This is what you have in your above code. If you are trying to write a code that can be compiled as both C and C++, get rid of the superfluous second typedef and just do
typedef struct foo foo;
...
struct foo
{
int bar;
};
(although in C++ the first typedef is superfluous as well).
I'm not sure why GCC rejects this code, but it appears it only objects because you're defining the same typedef twice.
This works:
typedef struct foo foo;
struct foo {
int bar;
};
And this works too, with the same effect:
typedef struct foo {
int bar;
} foo;
Why won't the compiler let me forward declare a typedef?
Assuming it's impossible, what's the best practice for keeping my inclusion tree small?
You can do forward typedef. But to do
typedef A B;
you must first forward declare A:
class A;
typedef A B;
For those of you like me, who are looking to forward declare a C-style struct that was defined using typedef, in some c++ code, I have found a solution that goes as follows...
// a.h
typedef struct _bah {
int a;
int b;
} bah;
// b.h
struct _bah;
typedef _bah bah;
class foo {
foo(bah * b);
foo(bah b);
bah * mBah;
};
// b.cpp
#include "b.h"
#include "a.h"
foo::foo(bah * b) {
mBah = b;
}
foo::foo(bah b) {
mBah = &b;
}
To "fwd declare a typedef" you need to fwd declare a class or a struct and then you can typedef declared type. Multiple identical typedefs are acceptable by compiler.
long form:
class MyClass;
typedef MyClass myclass_t;
short form:
typedef class MyClass myclass_t;
In C++ (but not plain C), it's perfectly legal to typedef a type twice, so long as both definitions are completely identical:
// foo.h
struct A{};
typedef A *PA;
// bar.h
struct A; // forward declare A
typedef A *PA;
void func(PA x);
// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
Because to declare a type, its size needs to be known. You can forward declare a pointer to the type, or typedef a pointer to the type.
If you really want to, you can use the pimpl idiom to keep the includes down. But if you want to use a type, rather than a pointer, the compiler has to know its size.
Edit: j_random_hacker adds an important qualification to this answer, basically that the size needs to be know to use the type, but a forward declaration can be made if we only need to know the type exists, in order to create pointers or references to the type. Since the OP didn't show code, but complained it wouldn't compile, I assumed (probably correctly) that the OP was trying to use the type, not just refer to it.
Using forward declarations instead of a full #includes is possible only when you are not intending on using the type itself (in this file's scope) but a pointer or reference to it.
To use the type itself, the compiler must know its size - hence its full declaration must be seen - hence a full #include is needed.
However, the size of a pointer or reference is known to the compiler, regardless of the size of the pointee, so a forward declaration is sufficient - it declares a type identifier name.
Interestingly, when using pointer or reference to class or struct types, the compiler can handle incomplete types saving you the need to forward declare the pointee types as well:
// header.h
// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;
typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;
// Using the name without the class/struct specifier requires fwd. decl. the type itself.
class C; // fwd. decl. type
typedef C* CPtr; // no class/struct specifier
typedef C& CRef; // no class/struct specifier
struct D; // fwd. decl. type
typedef D* DPtr; // no class/struct specifier
typedef D& DRef; // no class/struct specifier
I had the same issue, didn't want to mess with multiple typedefs in different files, so I resolved it with inheritance:
was:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
did:
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
Worked like a charm. Of course, I had to change any references from
BurstBoss::ParticleSystem
to simply
ParticleSystem
I replaced the typedef (using to be specific) with inheritance and constructor inheritance (?).
Original
using CallStack = std::array<StackFrame, MAX_CALLSTACK_DEPTH>;
Replaced
struct CallStack // Not a typedef to allow forward declaration.
: public std::array<StackFrame, MAX_CALLSTACK_DEPTH>
{
typedef std::array<StackFrame, MAX_CALLSTACK_DEPTH> Base;
using Base::Base;
};
This way I was able to forward declare CallStack with:
class CallStack;
As Bill Kotsias noted, the only reasonable way to keep the typedef details of your point private, and forward declare them is with inheritance. You can do it a bit nicer with C++11 though. Consider this:
// LibraryPublicHeader.h
class Implementation;
class Library
{
...
private:
Implementation* impl;
};
// LibraryPrivateImplementation.cpp
// This annoyingly does not work:
//
// typedef std::shared_ptr<Foo> Implementation;
// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
// C++11 allows us to easily copy all the constructors.
using shared_ptr::shared_ptr;
};
Like #BillKotsias, I used inheritance, and it worked for me.
I changed this mess (which required all the boost headers in my declaration *.h)
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
typedef boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;
into this declaration (*.h)
class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;
and the implementation (*.cpp) was
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
class VanillaAccumulator : public
boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>>
{
};
Another solution is to put the forward declarations and typedefs into a separate header and include that:
// ForwardDeclarations.h
#pragma once
namespace Foo
{
struct Bar;
typedef Bar Baz;
}
// SomeFile.h
#include "ForwardDeclarations.h"
Foo::Baz baz;
Of course this doesn't actually reduce the number of files to include and the compiler still has to read this file from the disk, but at least the contents are simpler than the full definition. You could add more forward declarations to the same file and include it in relevant places.