Domanda

Simple version of the problem:

library.h

 typedef library::whatever::something::complicated X;

Can I forward-declare X without including library.h?


Essentially what I want to do is this:

Foo.h :

// forward declare X

void foo (const X &);

Bar.h :

#include <library>
typedef library::type<blah>::whatever Bar;
typedef Bar X;

Foo.cpp :

#include <Foo.h>
#include <Bar.h>

foo (const X &) {...

main.cpp :

#include <Foo.h>
#include <Bar.h>

foo (X ());

The premise is that I don't want to have to include <library> unless I have to. Let's say it interacts badly with other headers, nevertheless these other headers want a declaration of foo. One would not be able to invoke foo() without including the library, but that's something for the .cpps to worry about.

If I wanted to have X be typedef'd to an ordinary class C, it would suffice to forward-declare C, but that won't work here.

I can forward-declare X as a typedef but AFAIK only if I already have a definition of library::type<blah> (and perhaps a definition of blah too).

The whole point of forward-declaring would be to not #include the definitions of these types.

Here is a related problem:

namespace std
{
    template <typename T>
    class vector;
}

typedef std :: vector <int> Buffer;

void foo (const Buffer &);

#include <vector> // ok until here

int main ()
{
    foo (Buffer ());
}

In this case the forward declaration of std::vector is incompatible with the definition. Let's pretend that I really really don't want to #include <vector> (or whatever external class it is).

Is there a way around this?

È stato utile?

Soluzione

You can't forward declare nested class, see this answer.

However, if your class is not nested, you can do it like this:

// inside library_fwd.hpp:
namespace library {
namespace whatever {

template <class T>
class Something;
typedef Something<int> IntSomething;

} // namespace whatever
} // namespace library

and:

// inside foo.cpp
#include "library_fwd.hpp"
void foo(const library::whatever::IntSomething&);

Your problem with std::vector example is about conflicting declarations. See std::vector. Fix:

namespace std {
  template <class T>
  class allocator;

  template <typename T, class Allocator>
  class vector;
}

typedef std::vector<int, std::allocator<int>> Buffer;

void foo(const Buffer &);

#include <vector> // now ok

int main () {
  foo (Buffer ());
}

PS example of some std lib forward declaration: http://en.cppreference.com/w/cpp/header/iosfwd

Altri suggerimenti

i think it's hard to do so, because typedef library::type<blah>::whatever Bar; requires the full definition of class library::type, it's not the forward-declare that can solve.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top