• Advertisement
Sign in to follow this  

[C++] Can I forward declare nested classes?

This topic is 4619 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know it's possible with classes within namespaces, but what about classes within classes? Eg.
struct A
{
  struct B
  {
  };
};

how can that be forward declared?

Share this post


Link to post
Share on other sites
Advertisement
Uhhh Dalleboy.. You do know that those aren't forward declarations, right (although doing that is useful to keep clutter down)? At any rate, I'm having this same problem, and I'd love it as well if someone knew how to do this.. And Ace, I've tried that, it didn't work for me.

Share this post


Link to post
Share on other sites
Quote:
Original post by SirLuthor
You do know that those aren't forward declarations, right (although doing that is useful to keep clutter down)?

This code contains the forward declaration of the class A::B. It also defines the class A.

class A
{
class B;

// A stuff...
};

Share this post


Link to post
Share on other sites

class A::B;

doesn't work in MSVC 6. You get these errors:

error C2653: 'A' : is not a class or namespace name
error C2079: 'B' uses undefined class 'A'

Share this post


Link to post
Share on other sites
Quote:
Original post by dalleboy
This code contains the forward declaration of the class A::B. It also defines the class A.
*** Source Snippet Removed ***

It may contain the forward declaration of B in A, but that is what I at least wish to avoid, because that requires I include the A header file, or copy it into the file, which is an even worse solution. The point is to be able to forward declare nested classes without defining the holding class as well.

Share this post


Link to post
Share on other sites
So nobody knows, or maybe it's actually not possible?

Share this post


Link to post
Share on other sites
It is not allowed because the outer class is still incomplete when you would forward declare the nested class. Consider, for example:


/* in first source file */
struct A;
struct A::B; // not allowed, but let's pretend it is

A::B *ptr = 0; // OK, pointer to nested class


/* in second source file */
struct A {
private:
struct B { // Oops, ptr was not OK after all!



Share this post


Link to post
Share on other sites
Quote:
Original post by SirLuthor
Quote:
Original post by dalleboy
This code contains the forward declaration of the class A::B. It also defines the class A.
*** Source Snippet Removed ***

It may contain the forward declaration of B in A, but that is what I at least wish to avoid, because that requires I include the A header file, or copy it into the file, which is an even worse solution. The point is to be able to forward declare nested classes without defining the holding class as well.


Are you the alternate account of the OP? I'm a bit confused here.

The OP Stated that they wanted to forward declare A::B, which one can using the method dalleboy posted.

Directly stating:

struct A;
struct A::B;

Is illegal. If you want this kind of behavior, I'd suggest making B a non-nested class... e.g:

struct B; //or B_Impl or whatever
struct A;

...

struct B {
...
};

...

struct A {
typedef ::B B;

...
};

A::B * ptr = ...;

Share this post


Link to post
Share on other sites
Nah MaulingMonkey, I've just been having that same problem as the OP, and felt like shoving my nose into another's thread [grin]

Share this post


Link to post
Share on other sites
Ahh okay ^_^.

I have a huge grudge against nested classes and don't use them*. I instead prefer to use typedefs to achieve my desired effect. For example, if I were implementing my own version of std::vector...:

namespace std { //you should almost never ever do this.

template < typename value_t >
class vector;

template < typename value_t >
class _Impl_vector_iterator {
friend class vector< value_type >;
public:
typedef value_t value_type;
private:
value_type * data ;

_Impl_vector_iterator ( value_type * data )
: data( data )
{
}
public:
bool operator==( const _Impl_vector_iterator & other ) const {
return data == other.data;
}
//...
};

template < typename value_t >
class vector {
public:
typedef std::size_t size_type;
typedef value_t value_type;
typedef _Impl_vector_iterator< value_type > iterator;
typedef _Impl_vector_iterator< const_value_type > const_iterator;
private:
size_type m_size; //I don't like pimpls for the most part, but...
value_type * data;
public:
size_type size( void ) const { //...people should use this function...
return m_size; //...so this is one of the two or three uses absolutely needed.
}
iterator begin( void ) {
return iterator( data ); //note: uses the private ctor, which is why we're a friend.
}
iterator end( void ) {
return iterator( data + size() ); //note: uses the private ctor again
}
const_iterator begin( void ) const {
return const_iterator( data );
}
const_iterator end( void ) const {
return const_iterator( data + size() ); //note: we use size() instead of m_size whenever possible.
}
//...
};
}



Note that this source is very (very) incomplete,

* with the very occasional exception, namely with Boost.Spirit which requires this syntax to define grammars, and similar cases of template-fu.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement