Использование локальных классов с алгоритмами STL
Я всегда задавался вопросом, почему вы не можете использовать локально определенные классы в качестве предикатов для алгоритмов STL.
В вопросе: Приближение алгоритмов STL, лямбда, локальных классов и других подходов, BubbaT упоминает, что" поскольку стандарт С++ запрещает использование локальных типов в качестве аргументов
Пример кода:
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. Поскольку С++ 11, законным является использование локального типа в качестве аргумента шаблона.
Ответы
Ответ 1
Он явно запрещен стандартом С++ 98/03.
С++ 11 удалите это ограничение.
Чтобы быть более полным:
Ограничения на типы, которые используемые в качестве параметров шаблона , перечислены в статье 14.3.1 С++ 03 (и С++ 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
Подводя итог, ограничение было ошибкой, которая была бы исправлена раньше, если бы стандарт развивался быстрее...
Сегодня говорят, что самые последние версии общих компиляторов позволяют это, наряду с предоставлением лямбда-выражений.
Ответ 2
Ограничение будет удалено в '0x, но я не думаю, что вы будете использовать их очень сильно. И это потому, что С++ - 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); })
}
Мой синтаксис в приведенном выше может быть не идеальным, но общая идея есть.