Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward declare typedef within C++ class

What's the best solution to forward declare a typedef within a class. Here's an example of what I need to solve:

class A;
class B;

class A
{
    typedef boost::shared_ptr<A> Ptr;

    B::Ptr foo();
};

class B
{
    typedef boost::shared_ptr<B> Ptr;

    A::Ptr bar();
};

I suppose I could just do the following:

boost::shared_ptr<B> foo();

But is there a more elegant solution?

like image 572
Tom Avatar asked Jun 06 '13 15:06

Tom


People also ask

Can I forward declare a typedef?

But you can't forward declare a typedef. Instead you have to redeclare the whole thing like so: typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value; Ah, but I don't have any of those classes declared either.

Can you forward declare in C?

In Objective-C, classes and protocols can be forward-declared like this: @class MyClass; @protocol MyProtocol; In Objective-C, classes and protocols can be forward-declared if you only need to use them as part of an object pointer type, e.g. MyClass * or id<MyProtocol>.

Can you forward declare a nested class?

You cannot forward declare a nested structure outside the container. You can only forward declare it within the container. Create a common base class that can be both used in the function and implemented by the nested class.

Can we use typedef in class?

Classes and structures can have nested typedefs declared within them.


2 Answers

There is no such thing as forward declaring a typedef unfortunately. However, there's a trick using late template instantiation:

template <typename T> class BImpl;

template <typename T>
class AImpl
{
public:
    typedef boost::shared_ptr<AImpl> Ptr;
    typename BImpl<T>::Ptr foo();
};

template <typename T>
class BImpl
{
public:
    typedef boost::shared_ptr<BImpl> Ptr;
    typename AImpl<T>::Ptr bar();
};

typedef AImpl<void> A;
typedef BImpl<void> B;

This should hopefully accomplish the thing you're aiming for.

like image 152
Ralph Tandetzky Avatar answered Oct 07 '22 08:10

Ralph Tandetzky


You're facing two distinct difficulties: 1. There are no forward declarations of typedefs 2. Forward declarations of nested types are not possible

There is no way around the second: you have to unnest the types.

One way around the first that I occasionally use is to make a derived type, and that yes, can be forwardly declared.

Say:

struct Ptr : shared_ptr<A> {};

This is a new type, but it is almost the same as a synonym. The problem, of course, is constructors, but that is getting better with C++11.

This answer, of course, is in general. For your specific case, I think you should define the Ptrs outside the classes and you would have no problem at all.

struct A;
struct B;
typedef shared_ptr<A> APtr;
typedef shared_ptr<B> BPtr;

and then the classes.

like image 39
migle Avatar answered Oct 07 '22 07:10

migle