Подтвердить что ты не робот

Интеллектуальные указатели, typedefs и forward declarations

Мне нравится использовать интеллектуальные указатели, и я видел немного кода, который делает приятным использование typedef make сделать их красивее. Например:

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

позволяет мне написать: A::pointer a(new A);

Но я ударил небольшую ошибку в моем счастье typedef: -/, передовые объявления...

Итак, представьте себе этот сценарий:

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

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

работает достаточно хорошо, но мне бы хотелось немного почистить его. К сожалению, это не работает

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_;
};

Я понимаю, почему в этот момент в файле компилятор не имеет информации о том, что B фактически имеет в нем тип с именем pointer.

У меня есть ощущение, что я застрял, используя старый подход, по крайней мере, для некоторых вещей, но мне бы хотелось услышать некоторые умные идеи.

4b9b3361

Ответ 1

Это использование typedefs не делает его красивее - оно бесполезно. Вы можете сделать shared_ptr неполным типом, поэтому просто используйте shared_ptr<B>.

Ответ 2

Если вы хотите разделить typedefs, вы, вероятно, захотите использовать пространства имен для их объявления:

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_;
};

Ответ 3

Я могу представить два подхода:

  • Вы можете создать шаблон ptr_for и использовать его примерно так: ptr_for<B>::type b_ptr_;
  • Вы можете использовать две структуры (я знаю, что это, вероятно, не то, что вы ищете), поэтому определения реализаций могут появляться после определений A и B.