Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

smart pointers, typedefs and forward declarations

I love using smart pointers, and have seen a bit of code which makes nice use of typedefs make make them prettier. For example:

struct A {
    typedef boost::shared_ptr<A> pointer;
};

allows me to write: A::pointer a(new A);

But I have hit a minor snag in my typedef happiness :-/, forward declarations...

So imagine this scenario:

struct B;
struct A {
    boost::shared_ptr<B> b_;
};

struct B {
    boost::shared_ptr<A> a_;
};

works well enough, but I'd love to clean that up a little. Unfortunately, this is doesn't work

struct B;
struct A {
    typedef boost::shared_ptr<A> pointer;
    B::pointer b_; // <-- error here
};

struct B {
    typedef boost::shared_ptr<B> pointer;
    A::pointer a_;
};

I understand why, at that point in the file, the compiler has no information that B in fact has a type in it named pointer.

I have a feeling that I am stuck using the old approach at least for some stuff, but I'd love to hear some clever ideas.

like image 784
Evan Teran Avatar asked Jun 16 '11 19:06

Evan Teran


People also ask

What are forward declarations in C?

In C++, Forward declarations are usually used for Classes. In this, the class is pre-defined before its use so that it can be called and used by other classes that are defined before this. Example: // Forward Declaration class A class A; // Definition of class A class A{ // Body };

What is forward declaration in Objective 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 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.


2 Answers

That use of typedefs doesn't make it prettier- it's worthless. You can make a shared_ptr to an incomplete type, so just use shared_ptr<B>.

like image 117
Puppy Avatar answered Oct 07 '22 13:10

Puppy


If you want to share typedefs you probably want to use namespaces for declaring them:

struct A;
struct B;

namespace Aimpl {
  typedef boost::shared_ptr<A> pointer;
}

namespace Bimpl {
  typedef boost::shared_ptr<B> pointer;
}

struct A {
    Bimpl::pointer b_;
};

struct B {
    Aimpl::pointer a_;
};
like image 28
Kirill V. Lyadvinsky Avatar answered Oct 07 '22 11:10

Kirill V. Lyadvinsky