Какие ограничения занимают место ISO С++ 03 в структурах, определенных в области функций?

Нам не разрешено определять функторную структуру внутри функции, потому что нельзя использовать функции объявленных структур в создании шаблонов функций.

Есть ли какие-либо другие существенные ошибки, о которых нужно знать? Например. это было бы плохо:

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

Ответы

Ответ 1

1. Стандарт С++ запрещает использование локально определенных классов с шаблонами.

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
    };
}

Ответ 2

Область локальных классов - это функция, в которой они определены. Но это не интересно само по себе 1.

Что делает интересные локальные классы: , если они реализуют некоторый интерфейс, тогда вы можете создавать экземпляры его (используя new) и возвращать их, тем самым делая реализацию доступной через указатель базового класса даже вне функции.

Некоторые другие факты о локальных классах:

  • Они не могут определять статические переменные-члены.

  • Они не могут получить доступ к нестатическим "автоматическим" локальным переменным вложенной функции. Но они могут получить доступ к переменным static.

  • Они могут использоваться в функциях шаблона. Однако они не могут использоваться как аргумент шаблона.

  • Если они определены внутри функции шаблона, то они могут использовать параметры шаблона прилагаемой функции.

  • Локальные классы являются окончательными, что означает, что пользователи, не входящие в эту функцию, не могут получить из локального класса функцию. Без локальных классов вам нужно будет добавить неназванное пространство имен в отдельной единицы перевода.

  • Локальные классы используются для создания функций батута, обычно называемых thunks.

Некоторые ссылки из Стандарта (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. Локальный класс не должен содержать статических данных.

Ответ 3

Локальные структуры/классы не могут содержать статические члены данных, а только статические функции-члены. Кроме того, они не могут быть шаблонами.

Ответ 4

Да. Локальные классы не могут использоваться в качестве параметров шаблона в С++ 03

Ответ 5

локальные структуры совершенно законны даже в С++ 98. Вы не можете использовать их с шаблонами в С++ 98, хотя вы можете в С++ 0x. g++ 4.5 поддерживает использование локальных структур с шаблонами в режиме -std = С++ 0x.