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

Вперед объявить typedef в классе С++

Какое лучшее решение для пересылки объявляет typedef внутри класса. Вот пример того, что мне нужно решить:

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();
};

Я полагаю, я мог бы просто сделать следующее:

boost::shared_ptr<B> foo();

Но есть ли более элегантное решение?

4b9b3361

Ответ 1

Нет такой вещи, как forward, объявляющее typedef, к сожалению. Однако есть трюк с использованием позднего шаблона:

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;

Это, надо надеяться, сделает то, к чему вы стремитесь.

Ответ 2

Вы сталкиваетесь с двумя различными трудностями: 1. Нет передовых деклараций typedefs 2. Переслать декларацию вложенных типов невозможно

Во второй нет пути: вы должны отключать типы.

Один из способов, с которым я иногда пользуюсь, состоит в том, чтобы создать производный тип, и что да, может быть объявлен вперед.

Скажи:

struct Ptr : shared_ptr<A> {};

Это новый тип, но он почти такой же, как синоним. Проблема, конечно, является конструктором, но с С++ 11 улучшается.

Этот ответ, конечно, вообще. Для вашего конкретного случая, я думаю, вы должны определить Ptrs вне классов, и у вас не было бы проблем вообще.

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

а затем классы.

Ответ 3

Вы не можете.

Но вы можете отделить определение Ptr классов:

class A;
class B;

template <typename T>
struct Traits {
    typedef std::shared_ptr<A>  Ptr; 
};

class A
{
    Traits<B>::Ptr foo();
};

class B
{
    Traits<A>::Ptr bar();
};

Если A и B не используют одни и те же типы, вы всегда можете специализировать Черты для всех типов.

Ответ 4

Нет способа переслать объявление либо

  • A typedef
  • Имя в другом классе

Итак - вы не можете перенаправить объявление typedef, и если бы вы могли, вы все равно не смогли бы этого сделать, потому что вам нужно было бы это сделать:

class B::Ptr;

и что невозможно

Ответ 5

Как отмечали другие, вы не можете переслать-объявить typedefs. Это частично потому, что typedefs не являются действительно "типами" своих собственных, а псевдонимов для других типов (отсюда эквивалентное понятие С++ 11 "псевдонима типа", например "использование Int = int;" ). Это означает, например, что typedefs не отображаются в элементах ABI, таких как искаженные имена, и поэтому компилятор действительно должен знать достаточно базового типа для удовлетворения всех требований ABI (в том числе о том, как манипулировать именем типа).