C ++ замыкания и шаблоны - PullRequest
       39

C ++ замыкания и шаблоны

4 голосов
/ 19 сентября 2009

Мы все знаем, что вы можете моделировать замыкания в C ++ 98, определяя локальные структуры / классы внутри функции. Но есть ли какая-то причина, по которой локально определенные структуры нельзя использовать для создания экземпляров шаблонов вне локальной области видимости?

Например, было бы очень полезно иметь возможность делать такие вещи:

void work(std::vector<Foo>& foo_array)
{
    struct compareFoo
    {
       bool operator()(const Foo& f1, const Foo& f2) const
       {
         return f1.bar < f2.bar;
       }
    };

    std::sort(foo_array.begin(), foo_array.end(), compareFoo());
}

Это было бы особенно полезно, если вы знаете, что вам не нужно использовать compareFoo где-либо еще в вашем коде. Но, увы, это не компилируется. Есть ли какая-то причина, по которой компилятор не может создать экземпляр функции-шаблона std :: sort, используя локально определенную структуру?

Ответы [ 4 ]

6 голосов
/ 19 сентября 2009

Нет лучшей причины, чем "это не разрешено стандартом".

Я считаю, что C ++ 0x снимет это ограничение и позволит вам свободно использовать локальные классы в качестве параметров шаблона. Но пока это запрещено.

6 голосов
/ 19 сентября 2009

См. GOTW # 58 - вы не можете использовать локально определенные классы в качестве аргументов для шаблонных типов, например, вектор не допускается.

Из стандарта C ++ (14.3.1 / 2):

   A local type, a type with no linkage, an unnamed
   type or a type compounded from any of these types
   shall not be used as a template-argument for a
   template type-parameter.  [Example:
    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
    }
   --end example]

Хотя я не читаю это как значение шаблонных функций, таких как std :: sort, не может использовать локальный класс в качестве аргумента, очевидно, gcc думает иначе.

Локальные классы не имеют связи (без глобального имени), что похоже на то, что помогает перегореть писателям компиляторов и вредит реальным программистам. Чтобы фактически разрешить использование локального класса S в vector<S> или некотором function<..,S>, я предполагаю, что сгенерированному объекту понадобится уникальное глобальное имя.

2 голосов
/ 19 сентября 2009

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

В нем говорится: локальный тип ... не должен использоваться в качестве аргумента шаблона для параметра типа шаблона.

В приведенном примере используется шаблон класса, но я полагаю, что нет оснований предполагать, что это ограничение не применимо к функциям шаблона.

Во всяком случае, мне интересно, в чем причина этого ограничения. Это кажется произвольным.

1 голос
/ 03 февраля 2012

Я знаю, что этот вопрос немного устарел, но более простым решением является включение стандартного режима c ++ 0x в g ++, поскольку он уже поддерживает создание экземпляров шаблонов с локально определенными типами.

g++ -std=c++0x filename.cpp -o filename
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...