3

次のコードを検討してください。

class A
{
private:
    class B {};
public:
    B f();
};

A a;

A::B g()
{
    return a.f();
}

コンパイラはこれを拒否します - A::B は非公開であるため、g は A::B を返すことができません。

しかし、ここで decltype を使用して g の戻り値を指定するとします。

class A
{
private:
    class B {};
public:
    B f();
};

A a;

decltype(a.f()) g()
{
    return a.f();
}

突然、正常にコンパイルされます (g++ >= 4.4 で)。

したがって、基本的には decltype を使用して、C++98 ではできなかった方法でアクセス指定子を回避しました。

これは意図的なものですか?これは良い習慣ですか?

4

1 に答える 1

5

アクセスは名前にのみ適用されます(特別な場合として、コンストラクタ/デストラクタに適用されます)。エンティティ自体には適用されません。仕様はさらに詳しく説明します

[注:アクセス制御は名前に適用されるため、アクセス制御がtypedef名に適用される場合、typedef名自体のアクセス可能性のみが考慮されます。typedefによって参照されるエンティティのアクセシビリティは考慮されません。例えば、

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

void f() {
  A::BB x; // OK, typedef name A::BB is public
  A::B y; // access error, A::B is private
}

—エンドノート]

ですから、ここであなたが発見したことは驚くべきことではありません。A::BC ++ 03でも、fと言っ&A::fて関数テンプレートに渡すことでアドレスを取得し、戻り型を推測することで、型を把握できます。

于 2011-01-16T09:16:58.763 に答える