Я не уверен, что понимаю вашу путаницу, но я просто изложу все факты и позволю вам разобраться.:)
В C ++ 03 это было законно:
#include <iostream>
int main()
{
struct func
{
void operator()(int x) const
{
std::cout << x << std::endl;
}
};
func f; // okay
f(-1); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
}
Но если бы мы попытались это сделать, это не было бы:
template <typename Func>
void exec(Func f)
{
f(1337);
}
int main()
{
// ...
exec(func); // not okay, local classes not usable as template argument
}
То, что осталосьу нас проблема: мы хотим определить предикаты, которые будут использоваться для этой функции, но мы не можем поместить это в функцию.Таким образом, мы должны были перенести это в любой внешний вид и использовать его там.Мало того, что это загромождает эту область с вещами, о которых никто больше не должен был знать, но это перемещало предикат от того, где это используется, делая более трудным читать код.
Это могло все еще быть полезным, для случайногоповторно использовал кусок кода внутри функции (например, в цикле выше; у вас мог быть предикат функции к некоторой сложной вещи с ее аргументом), но большую часть времени мы хотели использовать их в шаблонах.
C ++ 0x изменяет правила, чтобы позволить вышеуказанному коду работать.Они дополнительно добавили lambdas: синтаксис для создания объектов функций в виде выражений, например:
int main()
{
// same function as above, more succinct
auto func = [](int x){ std::cout << x << std::endl; };
// ...
}
Это точно так же, как описано выше, но проще.Так есть ли у нас еще какое-нибудь применение для «настоящих» локальных классов?Конечно.В конце концов, у Lambda нет полной функциональности:
#include <iostream>
template <typename Func>
void exec(Func func)
{
func(1337);
}
int main()
{
struct func
{
// note: not possible in C++0x lambdas
void operator()(const char* str) const
{
std::cout << str << std::endl;
}
void operator()(int val) const
{
std::cout << val << std::endl;
}
};
func f; // okay
f("a string, ints next"); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
exec(f); // okay
}
Тем не менее, с лямбдами вы, вероятно, не увидите локальные классы больше, чем раньше, но по совершенно другим причинам: один почти бесполезен, другойпочти заменен.