Вперед объявить typedef в классе C++
какое лучшее решение для пересылки объявления 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();
но есть ли более изящное решение?
5 ответов
нет такой вещи, как вперед объявлении 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;
надеюсь, это должно выполнить то, к чему вы стремитесь.
вы столкнулись с двумя различными трудностями: 1. Нет прямых объявлений typedefs 2. Прямые объявления вложенных типов невозможны
нет никакого способа обойти второй: вы должны unnest типы.
один из способов обойти первый, который я иногда использую, - это сделать производный тип, и это да, может быть объявлено вперед.
говорят:
struct Ptr : shared_ptr<A> {};
Это новый тип, но он почти такой же, как синоним. Проблема, конечно, есть конструкторы, но это становится лучше с C++11.
этот ответ, Конечно, в целом. Для вашего конкретного случая, я думаю, вы должны определить PTR вне классов, и у вас не будет никаких проблем.
struct A;
struct B;
typedef shared_ptr<A> APtr;
typedef shared_ptr<B> BPtr;
а затем классы.
вы не можете.
но вы можете разделить определение 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 не имеют одинаковых типов, вы всегда можете специализировать признаки для всех типов.
нет никакого способа вперед объявить либо
- A
typedef
- имя в другом классе
Итак - вы не можете переслать объявление typedef
и если бы вы могли, вы все равно не смогли бы этого сделать, потому что вам нужно было бы сделать это:
class B::Ptr;
и это невозможно
Как отмечали другие, вы не можете вперед объявить typedefs. Это отчасти потому, что typedefs на самом деле не являются "типами", а псевдонимами для других типов (отсюда эквивалентное понятие C++11 "псевдоним типа", такое как "использование Int = int;"). Это означает, например, что typedefs не отображаются в элементах ABI, таких как искаженные имена, и поэтому компилятор действительно должен знать достаточно базового типа, чтобы удовлетворить все требования ABI (включая как исказить имя типа).