10

C++ 標準の 5.1.1/3 では [expr.prim.general]

他のコンテキストのオブジェクト式とは異なり、*this は、メンバー関数本体の外部でクラス メンバーにアクセスする目的で完全な型である必要はありません。宣言の前に宣言されたクラス メンバーのみが表示されます。

そして、この例:

struct A {
    char g();
    template<class T> auto f(T t) -> decltype(t + g()) 
    { return t + g(); }
};
template auto A::f(int t) -> decltype(t + g());

引用と例を説明できますか?ここで示されているのは正確には何ですか?

4

3 に答える 3

6

これは具体的にどのような例ですか?ここで示されているステートメントはどれですか?

示されているステートメントは次のとおりです。

他のコンテキストでのオブジェクト式とは異なり、*this は、メンバー関数本体の外部でのクラス メンバー アクセス (5.2.5) のために完全な型である必要はありません。

メンバー関数の本体の外側には、 への呼び出しがあります。g()つまり、this->g(). そこでは、*this(つまりA) の型が完全ではありません。

C++11 標準のパラグラフ 9.2/2 によると:

class-specifier}を閉じると、クラスは完全に定義されたオブジェクト型 (3.9) (または完全な型) と見なされます。class member-specification内では、クラスは、関数本体、デフォルト引数、および非静的データ メンバーの波括弧または等号初期化子 (ネストされたクラス内のそのようなものを含む) 内で完全であると見なされます。それ以外の場合は、独自のクラスmember-specification内で不完全と見なされます。

于 2013-05-13T14:13:44.960 に答える
2

まず、すべてのメンバー アクセス式がコンパイラによって変換されます。

struct X{
  int a;
  void f(){}
  void g(int b){
    int x = a + b; // actually: int x = (*this).a + b
    f(); // actually: (*this).f();
  }
};

§9.3.1 [class.mfct.non-static] p3

[...] id-expression(*this)は、 (9.3.2) を演算子の左側の後置式として使用して、クラス メンバー アクセス式 (5.2.5) に変換されます.。[...]

ここで、標準の例では、末尾の戻り値の型で、別のメンバー関数の本体の外側でメンバー関数を呼び出します。そして、その呼び出しも変換されます。

template<class T> auto f(T t) -> decltype(t + (*this).g()) 
{ return t + (*this).g(); }

メンバー関数本体の外側では、*this明らかに不完全な型です。これは、使用前に宣言された名前にのみアクセスできることを意味しますが、その部分は*this使用にのみ適用されるわけではありません。

struct X{
  using typeA = int;
  typeA f(); // OK, 'typeA' has been declared before

  typeB g(); // Error: 'typeB' not declared before usage
  using typeB = float;
};
于 2013-05-13T14:20:10.927 に答える