質問
クラス名のtypedefでは、friend宣言のためのクラス名のように動作しない理由を誰もが知っていますか?
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
};
解決
これは、現在はできません。 (私はそれが面白いので、ちょうどそれを見て)私はまだその理由を知りません。アップデート:<のhref = "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520:あなたは友人としてのtypedef-名をサポートする最初の提案に理由を見つけることができます。 PDF」のrel = "noreferrer"> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf を。その理由は、標準のみ詳述型指定子をサポートしていることです。これはのみを許可するのは簡単だし、友人として宣言されたエンティティがまだ宣言されていない場合、それは周囲の名前空間のメンバーにすることになると言います。しかし、これは(クラスはその後、例えば必要とされる)を使用すると、テンプレートパラメータを使用したい場合は、あなたがしなければならないということを意味します。
friend class T;
しかし、それは別の問題をもたらし、それがゲイン価値がない考え出しました。今、紙は、追加型指定が与えられることを可能にすることを提案している(これは、テンプレートのパラメータおよび型定義、名前の使用を可能にするように)。
(2010による)次のC ++バージョンがそれを行うことができるようになります。
標準にこの更新された提案書を参照してください: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdfする。これは、名前だけでなく、友人として宣言された型として使用するテンプレートパラメータのtypedefを許可しません。
他のヒント
私の知る限り、C ++のtypedefでは本格的なシノニムを作成しません。言い換えれば、それはマクロのようではありません。
の制約の中では、シノニムがクラスまたは構造体の接頭辞の後に現れることができない、またはデストラクタまたはコンストラクタ名として使用されることです。あなたはまた、同義語をサブクラス化することはできません。私はまた、あなたが友人にそれをすることはできません意味で賭けるでしょう。
私はVC ++ 8.0のコードで試してみました
...
class C
{
public:
friend class A;
friend X;
friend B::SUPERCLASS;
};
...
これは、エラーなしでコンパイルされます。
私はMSの特定のかどうか。
知りませんのtypedefは、タイプを定義します。友人はその後、宣言クラスの非公共エリアへの「アクセス」を持っている、友人のクラスや関数を(略スコープ)を宣言decls ...
プリミティブ、すなわち、フロートまたはINT *は、などのコードと範囲を定義しません 彼らはとにかく、クラスを「使用」しないでください。
忘れてはいけない、こともできますのtypedefで「パック」呼び出し規約、アライメントはattribsと他のコンパイラの特定のもの、すなわち、同じクラスではなく、明確なアライメントはattribsで実装複数のベクトル型。 =>タイプは、クラスではなく、逆もまた同様である。
IMHO、typedefの友人を宣言すると便利ですが、どこからでも「クラスのtypedefが」友人のように設定することができたときに、友情はテンプレートが過度に使用されている、特に場合は、非常に不可解なので、エラーが発生しやすいになることができます。
広範囲の依存性のため、プロジェクト全体の単一のtypedef缶混乱を無効化。 テンプレートの友人や0Xテンプレートのtypedefは有用であるが、フレンド宣言の規則を緩和しません。
私は友人のtypedefに関するあらゆる提案を知りません。