7

次のコードは、GCC4.4.6およびComeau4.3.10を使用してコンパイルされます。

#include <iostream>

struct A { int name; };
template<typename T> struct C : T { using T::name; };
struct B : private A { friend struct C<B>; };

int main()
{
    C<B> o;
    o.name = 0;
}

VC++10では次のエラーが発生します。

main.cpp(4): error C2877: 'A::name' is not accessible from  'A'
main.cpp(10): error C2247: 'A::name' not accessible because 'B' uses 'private' to inherit from 'A'

これを可能にする優れたクロスコンパイラの回避策はo.name = 0;何ですか?

注:using A::name toを追加するとB問題は解決しますが、メンバーはすべてのユーザーに公開されA::nameますが、特定のテンプレートのインスタンス化、つまり。にのみ表示される必要がありますC<B>

4

2 に答える 2

5

回避策は@kerrekSBが提案したものでありusing A::name;、クラスに追加しBます。

struct A { int name; };
template<typename T> struct C : T { using T::name; };

struct B : private A { 
using A::name; 
friend struct C<B>;
};

最初の例は機能しませんでした。クラスAはプライベートBでクラスC<B>はフレンドですが、のオブジェクトからBメンバーにアクセスすると、クラスにメンバーがないため、lineで問題が発生します。クラスのオブジェクトを介してメンバーにアクセスしようとしたときにメンバーを見つけるのはスコープ検索ですnameC<B>using T::name;BnamenameB

編集 :

A :: nameを使用してBに追加すると問題は解決しますが、A :: nameメンバーはすべての人に公開されますが、特定のテンプレートのインスタンス化、つまりCにのみ表示される必要があります。

その場合は、using A::name;クラスのプライベートセクションでステートメントをB宣言するだけです。

struct B : private A {
protected: using A::name; 
public:
friend struct C<B>;
};
于 2012-09-06T07:59:34.993 に答える
2

メンバーusing-declarationsを使用する場合、gccとVC++の間で可視性の考慮事項に根本的な違いがあるようです。テンプレートなしのこの簡略化された例を確認してください。

struct A { int name; };
struct B: private A { friend struct C; };
struct C: B {using B::name; };

int main()
{
   C o;
   o.name = 0;
}

gccでコンパイルされますが、VC ++ではコンパイルされません(基本的に質問と同じエラーが発生します)。誰がそれを正しく行っているかについては、標準を参照する必要があります...

于 2012-09-06T08:10:21.487 に答える