2009-04-12 2 views
48

Я всегда задавался вопросом, почему вы не можете использовать локально определенные классы в качестве предикатов для алгоритмов STL.Использование локальных классов с алгоритмами STL

В вопросе: Approaching STL algorithms, lambda, local classes and other approaches, BubbaT упоминает говорит, что «Поскольку стандарт C++ запрещает локальные типы, которые будут использоваться в качестве аргументов»

Пример кода:

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    struct even : public std::unary_function<int,bool> 
    { 
     bool operator()(int x) { return !(x % 2); } 
    }; 
    std::remove_if(v.begin(), v.end(), even()); // error 
} 

Кто-нибудь знает, где в Стандарт - это ограничение? В чем обоснование отказа от местных типов?


EDIT: Так как C++ 11, он является законным использование локального типа в качестве аргумента шаблона.

ответ

50

Это явно запрещено стандартом C++ 98/03.

C++ 11 удалите это ограничение.

Чтобы быть более полным:

ограничения на типы, которые используются в качестве параметров шаблона перечислены в статье 14.3.1 из C++ 03 (и C++ 98) стандарт:

Местного типа, тип, без связи, безымянного типа или типа усугубляется от любого из этих типов не могут быть использованы как аргумент шаблона для параметра типа шаблона .

template <class T> class Y { /* ... */ }; 
void func() { 
     struct S { /* ... */ }; //local class 
     Y<S> y1; // error: local type used as template-argument 
     Y< S* > y2; // error: pointer to local type used as template-argument } 

Источник и более подробная информация: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

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

Это сказал сегодня самые последние версии общих компиляторов позволяют это, наряду с предоставлением лямбда-выражений.

+0

Я знаю, но я хотел бы знать, где посмотреть, могу ли я понять, почему. У вас есть ссылка на стандарт? –

+0

Вы ссылаетесь на 14.3.1.2, "аргументы типа шаблона"? – greyfade

+0

Я добавил некоторые сведения и ссылку, которые могут помочь. Подводя итог, ограничение было ошибкой, которая была бы быстро исправлена, если бы стандарт развивался быстрее ... – Klaim

5

Ограничение будет удалено в '0x, но я не думаю, что вы будете использовать их очень много. И это потому, что C++ - 0x будет иметь lambdas! :)

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    std::remove_if(v.begin() 
       , v.end() 
       , [] (int x) -> bool { return !(x%2); }) 
} 

Мой синтаксис в приведенном выше примере может быть не идеальным, но общая идея есть.

+0

Я знал о лямбдах. Фактически, то, чего я хотел достичь, является самым близким с нынешним стандартом. Вариант решения Java предлагает. –

+0

И каким образом это ответ на реальный вопрос (не говоря уже о том, что стоит 4 голоса)? –

+0

@ChristianRau:;) Я понимаю, почему ты так сказал. Вопрос в том, почему они не разрешены, и первая строка ответа адресована именно этому. он был удален, поэтому не должно было быть веских оснований для ограничения. В то время я ясно думал, что лямбды стоит упомянуть. Теперь, конечно, через 3 года лямбды хорошо известны, поэтому они больше не новости! –

Смежные вопросы