14

関数テンプレートのインスタンス化で関数宣言構造体を使用することは許可されていないため、関数内に関数構造体を定義することは許可されていません。

知っておくべき他の重要な落とし穴はありますか?たとえば、これは悪いことです:

int foo()
{
    struct Scratch
    {
        int a, b, c;
    };
    std::vector<Scratch> workingBuffer;
    //Blah Blah
}
4

5 に答える 5

23

1. C ++標準では、テンプレートでローカルに定義されたクラスを使用することは禁止されています。

14.3.1 / 2ローカル型、リンケージのない型、名前のない型、またはこれらの型のいずれかから複合された型は、テンプレート型パラメータのテンプレート引数として使用してはなりません。

コード例:

    template <class T> class X { /* ... */ };
    void f()
    {
      struct S { /* ... */ };
      X<S> x3;  // error: local type used as
                //  template-argument
      X<S*> x4; // error: pointer to local type
                //  used as template-argument
    }

IBMの資料からもう少し参考資料を示します。

2.ローカルクラスの宣言では、型名、列挙、囲んでいるスコープの静的変数、および外部変数と関数のみを使用できます。

コード例:

int x;                         // global variable
void f()                       // function definition
{
      static int y;            // static variable y can be used by
                               // local class
      int x;                   // auto variable x cannot be used by
                               // local class
      extern int g();          // extern function g can be used by
                               // local class

      class local              // local class
      {
            int g() { return x; }      // error, local variable x
                                       // cannot be used by g
            int h() { return y; }      // valid,static variable y
            int k() { return ::x; }    // valid, global x
            int l() { return g(); }    // valid, extern function g
      };
}

int main()
{
      local* z;                // error: the class local is not visible
      return 0;
}

3.ローカルクラスに静的データメンバーを含めることはできません

コード例:

void f()
{
    class local
    {
       int f();              // error, local class has noninline
                             // member function
       int g() {return 0;}   // valid, inline member function
       static int a;         // error, static is not allowed for
                             // local class
       int b;                // valid, nonstatic variable
    };
}
于 2011-06-20T18:12:30.073 に答える
2

ローカルクラスのスコープは、それらが定義されている関数ですが、それ自体は興味深いものではありません1

ローカルクラスが興味深いのは、それらが何らかのインターフェイスを実装している場合、(を使用して)そのインスタンスを作成してnew返すことができるため、関数の外部でも基本クラスポインタを介して実装にアクセスできることです。

ローカルクラスに関するその他の事実:

  • 静的メンバー変数を定義することはできません。

  • それらは、囲んでいる関数の非静的な「自動」ローカル変数にアクセスできません。しかし、彼らはstatic変数にアクセスできます。

  • テンプレート関数で使用できます。ただし、テンプレート引数として使用することはできません。

  • テンプレート関数内で定義した場合は、囲んでいる関数のテンプレートパラメーターを使用できます。

  • ローカルクラスはfinalです。つまり、関数外のユーザーはローカルクラスから関数に派生できません。ローカルクラスがない場合は、名前のない名前空間を別の翻訳単位に追加する必要があります。

  • ローカルクラスは、通常サンクと呼ばれるトランポリン関数を作成するために使用されます。

標準(2003)からのいくつかの参照

9.8ローカルクラス宣言[class.local]

\1。クラスは関数定義内で定義できます。このようなクラスはローカルクラスと呼ばれます。ローカルクラスの名前は、それを囲むスコープに対してローカルです。ローカルクラスは、囲んでいるスコープのスコープ内にあり、囲んでいる関数と同じように、関数の外部の名前にアクセスできます。ローカルクラスの宣言では、型名、静的変数、外部変数と関数、および囲んでいるスコープの列挙子のみを使用できます。

[Example:

int x;
void f()
{
   static int s ;
   int x;
   extern int g();

   struct local {
      int g() { return x; } // error: x is auto
      int h() { return s; } // OK
      int k() { return ::x; } // OK
      int l() { return g(); } // OK
   };
// ...
}
local* p = 0; // error: local not in scope

—end example]

\2。囲み関数には、ローカルクラスのメンバーへの特別なアクセス権はありません。通常のアクセスルール(11節)に従います。ローカルクラスのメンバー関数は、定義されている場合は、クラス定義内で定義されるものとします。

\3。クラスXがローカルクラスの場合、ネストされたクラスYはクラスXで宣言され、後でクラスXの定義で定義されるか、後でクラスXの定義と同じスコープで定義されます。ローカルクラス内にネストされたクラスはローカルクラス。

\4。ローカルクラスには静的データメンバーを含めないでください。

于 2011-06-20T18:17:55.823 に答える
1

ローカル構造体/クラスは静的データメンバーを持つことができず、静的メンバー関数のみを持つことができます。また、テンプレートにすることはできません。

于 2011-06-20T18:17:48.977 に答える
0

ローカル構造体は、C++98でも完全に合法です。ただし、C ++ 98ではテンプレートで使用できませんが、C++0xでは使用できます。g ++ 4.5は、-std = c++0xモードのテンプレートでローカル構造体を使用することをサポートします。

于 2011-06-20T18:21:29.403 に答える
0

はい。C ++ 03では、ローカルクラスをテンプレートパラメータとして使用することはできません。

于 2011-06-20T18:11:49.323 に答える