Вперед объявить 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();
Но есть ли более элегантное решение?
Ответы
Ответ 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 (в том числе о том, как манипулировать именем типа).