为什么我不能通过typedef声明朋友?

时间:2008-12-24 19:37:20

标签: c++

有谁知道为什么类名的typedef不像朋友声明的类名那样工作?

class A
{
public:
};

class B : public A
{
public:
   typedef A SUPERCLASS;
};

typedef A X;

class C
{
public:
   friend class A;             // OK
   friend class X;             // fails
   friend class B::SUPERCLASS; // fails
};

4 个答案:

答案 0 :(得分:9)

目前还不能。我不知道原因(只是查找它,因为我发现它很有趣)。更新:您可以在第一个提案中找到支持typedef-names为朋友的原因:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf。原因是标准仅支持详细类型说明符。很容易只允许那些,并且如果声明为expert的实体尚未声明,它将成为周围命名空间的成员。但这意味着如果你想使用模板参数,你必须这样做(例如,需要一个类)

friend class T;

但这带来了额外的问题,并且认为这不值得。现在,本文建议允许给出其他类型说明符(这样就可以使用模板参数和typedef-names)。

下一个C ++版本(由于2010年)将能够做到这一点。

请参阅此标准的更新提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf。它不仅允许typedef名称,还允许将模板参数用作声明为friend的类型。

答案 1 :(得分:1)

AFAIK,在C ++中,typedef在与类结合使用时不会创建完整的同义词。换句话说,它不像一个宏。

其中的限制是同义词不能出现在类或结构前缀之后,或者用作析构函数或构造函数名称。您也不能将同义词子类化。我敢打赌,这也意味着你不能和它交朋友。

答案 2 :(得分:1)

我在VC ++ 8.0中尝试了代码:

...
class C
{
public:
  friend class A;       
  friend X;             
  friend B::SUPERCLASS; 
};
...

编译时没有错误。

我不知道它是否具体是MS。

答案 3 :(得分:0)

typedef定义一种类型。朋友decls声明朋友类或函数(实质上是范围),然后“访问”声明类的非公共区域......

Primitives,i.E。 float或int *没有用代码等定义范围, 无论如何,他们并没有“使用”这门课程。

不要忘记,您还可以在typedef中“打包”调用约定,对齐属性和其他编译器特定内容,即由同一类实现但具有不同对齐属性的多个向量TYPES。 =>类型不是类,反之亦然。

恕我直言,声明朋友的typedef可能很有用,但是当任何地方的“class typedefs”都可以设置为朋友时,友谊会变得非常难以理解,因此容易出错,尤其是在过度使用模板的情况下。

由于广泛的依赖性,使单个typedef无效会使整个项目陷入混乱。 模板朋友和0x模板typedef很有用,但不要放松朋友声明的规则。

我不知道有关朋友typedef的任何建议。