在C ++类中转发声明typedef

时间:2013-06-06 15:54:09

标签: c++ typedef declaration forward

在类中声明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 个答案:

答案 0 :(得分:13)

不幸的是,没有向前声明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 :(得分:4)

你面临着两个截然不同的困难: 1.没有typedef的前向声明 2.无法对嵌套类型进行前向声明

第二种方法是没有办法:你必须取消这些类型。

我偶尔使用的第一种方法是创建一个派生类型,是的,可以向前声明。

说:

struct Ptr : shared_ptr<A> {};

这是一种新类型,但它几乎与同义词相同。 当然,问题在于构造函数,但是使用C ++ 11会越来越好。

这个答案当然是一般性的。对于你的具体情况,我认为你应该在课外定义Ptrs,你就没有问题了。

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

然后是课程。

答案 2 :(得分:2)

你不能。

但是你可以解耦类的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不共享相同的类型,您始终可以专门针对所有类型的特征。

答案 3 :(得分:1)

无法转发声明

  1. A typedef
  2. 另一个班级的名字
  3. 所以 - 你不能转发声明typedef,如果可以的话,你仍然无法做到这一点,因为你需要这样做:

    class B::Ptr;
    

    那是不可能的

答案 4 :(得分:1)

正如其他人所说,你不能转发声明typedef。这部分是因为typedef不是它们自己的“类型”,而是其他类型的别名(因此C ++ 11等同于“类型别名”的概念,例如“using Int = int;”)。这意味着,例如,typedef不会出现在ABI元素中,例如错位名称,因此编译器必须足够了解底层类型以满足所有ABI要求(包括如何破坏类型名称)。 / p>